You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by se...@apache.org on 2009/03/05 18:52:21 UTC

svn commit: r750522 - in /cxf/trunk: common/common/src/main/java/org/apache/cxf/common/util/ rt/core/src/main/java/org/apache/cxf/bus/spring/ rt/core/src/main/java/org/apache/cxf/interceptor/ rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/ rt...

Author: sergeyb
Date: Thu Mar  5 17:52:17 2009
New Revision: 750522

URL: http://svn.apache.org/viewvc?rev=750522&view=rev
Log:
JAXRS : fixing a bunch of exception-related issues on the outbound path

Added:
    cxf/trunk/common/common/src/main/java/org/apache/cxf/common/util/SystemUtils.java   (with props)
    cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/CustomOutInterceptor.java   (with props)
    cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerStreamingTest.java   (with props)
Modified:
    cxf/trunk/rt/core/src/main/java/org/apache/cxf/bus/spring/BusApplicationContext.java
    cxf/trunk/rt/core/src/main/java/org/apache/cxf/interceptor/AbstractOutDatabindingInterceptor.java
    cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/MessageContext.java
    cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/MessageContextImpl.java
    cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/Messages.properties
    cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/WebApplicationExceptionMapper.java
    cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/tl/ThreadLocalMessageContext.java
    cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/interceptor/JAXRSInInterceptor.java
    cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/interceptor/JAXRSOutInterceptor.java
    cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/AbstractConfigurableProvider.java
    cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/AbstractJAXBProvider.java
    cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/BinaryDataProvider.java
    cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/JAXBElementProvider.java
    cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/JSONProvider.java
    cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/SourceProvider.java
    cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/InjectionUtils.java
    cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/JAXRSUtils.java
    cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/multipart/AttachmentUtils.java
    cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/provider/ProviderFactoryTest.java
    cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/BookServer.java
    cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/BookStore.java
    cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerBookTest.java

Added: cxf/trunk/common/common/src/main/java/org/apache/cxf/common/util/SystemUtils.java
URL: http://svn.apache.org/viewvc/cxf/trunk/common/common/src/main/java/org/apache/cxf/common/util/SystemUtils.java?rev=750522&view=auto
==============================================================================
--- cxf/trunk/common/common/src/main/java/org/apache/cxf/common/util/SystemUtils.java (added)
+++ cxf/trunk/common/common/src/main/java/org/apache/cxf/common/util/SystemUtils.java Thu Mar  5 17:52:17 2009
@@ -0,0 +1,63 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.cxf.common.util;
+
+/**
+ * Utility class for checking well-known system properties
+ *
+ */
+public final class SystemUtils {
+    
+    public static final String OUT_BUFFERING = "org.apache.cxf.output.buffering";
+    public static final String SPRING_VALIDATION_MODE = "org.apache.cxf.spring.validation.mode";
+    
+    private SystemUtils() {
+        
+    }
+
+    /**
+     * Checks org.apache.cxf.output.buffering property value, defaults to false 
+     * @return true if output buffering is enabled
+     */
+    public static boolean isBufferingEnabled() { 
+        return Boolean.getBoolean(System.getProperty(OUT_BUFFERING, "false"));    
+    }
+    
+    /**
+     * Checks if org.apache.cxf.output.buffering property was explicitly set 
+     * @return true if it was set
+     */
+    public static boolean isBufferingSet() { 
+        return System.getProperty(OUT_BUFFERING) != null;    
+    }
+    
+    /**
+     * Gets org.apache.cxf.spring.validation.mode property value if available 
+     * @return Spring validation mode
+     */
+    public static String getSpringValidationMode() {
+        String mode = System.getProperty(SPRING_VALIDATION_MODE);
+        if (mode == null) {
+            mode = System.getProperty("spring.validation.mode");
+        }
+        return mode;
+    }
+    
+}

Propchange: cxf/trunk/common/common/src/main/java/org/apache/cxf/common/util/SystemUtils.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cxf/trunk/common/common/src/main/java/org/apache/cxf/common/util/SystemUtils.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Modified: cxf/trunk/rt/core/src/main/java/org/apache/cxf/bus/spring/BusApplicationContext.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/core/src/main/java/org/apache/cxf/bus/spring/BusApplicationContext.java?rev=750522&r1=750521&r2=750522&view=diff
==============================================================================
--- cxf/trunk/rt/core/src/main/java/org/apache/cxf/bus/spring/BusApplicationContext.java (original)
+++ cxf/trunk/rt/core/src/main/java/org/apache/cxf/bus/spring/BusApplicationContext.java Thu Mar  5 17:52:17 2009
@@ -33,6 +33,7 @@
 
 import org.apache.cxf.common.classloader.ClassLoaderUtils;
 import org.apache.cxf.common.logging.LogUtils;
+import org.apache.cxf.common.util.SystemUtils;
 import org.apache.cxf.configuration.Configurer;
 import org.springframework.beans.factory.support.DefaultListableBeanFactory;
 import org.springframework.beans.factory.xml.BeansDtdResolver;
@@ -227,10 +228,7 @@
         }
         reader.setNamespaceHandlerResolver(nsHandlerResolver);
         
-        String mode = System.getProperty("org.apache.cxf.spring.validation.mode");
-        if (mode == null) {
-            mode = System.getProperty("spring.validation.mode");
-        }
+        String mode = SystemUtils.getSpringValidationMode();
         if (null != mode) {
             reader.setValidationModeName(mode);
         }

Modified: cxf/trunk/rt/core/src/main/java/org/apache/cxf/interceptor/AbstractOutDatabindingInterceptor.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/core/src/main/java/org/apache/cxf/interceptor/AbstractOutDatabindingInterceptor.java?rev=750522&r1=750521&r2=750522&view=diff
==============================================================================
--- cxf/trunk/rt/core/src/main/java/org/apache/cxf/interceptor/AbstractOutDatabindingInterceptor.java (original)
+++ cxf/trunk/rt/core/src/main/java/org/apache/cxf/interceptor/AbstractOutDatabindingInterceptor.java Thu Mar  5 17:52:17 2009
@@ -29,6 +29,7 @@
 import javax.xml.stream.events.XMLEvent;
 import javax.xml.validation.Schema;
 
+import org.apache.cxf.common.util.SystemUtils;
 import org.apache.cxf.databinding.DataWriter;
 import org.apache.cxf.endpoint.Endpoint;
 import org.apache.cxf.message.Attachment;
@@ -72,8 +73,9 @@
         XMLStreamWriter xmlWriter = origXmlWriter;
         CachingXmlEventWriter cache = null;
         
-        if (shouldValidate(message) && !isRequestor(message)) {
-            //need to cache the events in case validation fails
+        // need to cache the events in case validation fails or buffering is enabled
+        if (shouldValidate(message) && !isRequestor(message)
+            || SystemUtils.isBufferingEnabled()) {
             cache = new CachingXmlEventWriter();
             try {
                 cache.setNamespaceContext(origXmlWriter.getNamespaceContext());

Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/MessageContext.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/MessageContext.java?rev=750522&r1=750521&r2=750522&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/MessageContext.java (original)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/MessageContext.java Thu Mar  5 17:52:17 2009
@@ -36,7 +36,7 @@
 public interface MessageContext {
     
     Object get(Object key);
-    void put(Object key, Object value, boolean outbound);
+    void put(Object key, Object value);
     
     UriInfo getUriInfo();
     Request getRequest();

Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/MessageContextImpl.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/MessageContextImpl.java?rev=750522&r1=750521&r2=750522&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/MessageContextImpl.java (original)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/MessageContextImpl.java Thu Mar  5 17:52:17 2009
@@ -49,7 +49,6 @@
 public class MessageContextImpl implements MessageContext {
 
     private Message m;
-    
     public MessageContextImpl(Message m) {
         this.m = m;
     }
@@ -112,11 +111,7 @@
         return JAXRSUtils.createServletResourceValue(m, ServletContext.class);
     }
 
-    public void put(Object key, Object value, boolean outbound) {
-        if (outbound) {
-            throw new UnsupportedOperationException(
-                      "MessageContext.put() is not supported for outbound properties");
-        }
+    public void put(Object key, Object value) {
         m.put(key.toString(), value);
     }
 

Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/Messages.properties
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/Messages.properties?rev=750522&r1=750521&r2=750522&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/Messages.properties (original)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/Messages.properties Thu Mar  5 17:52:17 2009
@@ -18,6 +18,6 @@
 #    under the License.
 #
 #
-WEB_APP_EXCEPTION=WebApplicationExceptionMapper has caught an exception {0}
+WEB_APP_EXCEPTION=WebApplicationException has been caught : {0}
 DEFAULT_EXCEPTION_MESSAGE=Internal server exception occurred. Please consult logs for more information.
 

Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/WebApplicationExceptionMapper.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/WebApplicationExceptionMapper.java?rev=750522&r1=750521&r2=750522&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/WebApplicationExceptionMapper.java (original)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/WebApplicationExceptionMapper.java Thu Mar  5 17:52:17 2009
@@ -38,14 +38,20 @@
     private static final ResourceBundle BUNDLE = BundleUtils.getBundle(WebApplicationExceptionMapper.class);
     
     public Response toResponse(WebApplicationException ex) {
-        if (LOG.isLoggable(Level.FINE)) {
+        if (LOG.isLoggable(Level.WARNING)) {
+            String message = ex.getCause() == null ? ex.getMessage() : ex.getCause().getMessage();
+            if (message == null) {
+                if (ex.getCause() != null) {
+                    message = "cause is " + ex.getCause().getClass().getName();
+                } else {
+                    message = "no cause is available";
+                }
+            }
             org.apache.cxf.common.i18n.Message errorMsg = 
-                new org.apache.cxf.common.i18n.Message("WEB_APP_EXCEPTION", 
-                    BUNDLE, ex.getCause() == null ? ex.getMessage() : ex.getCause().getMessage());
-            LOG.fine(errorMsg.toString());
+                new org.apache.cxf.common.i18n.Message("WEB_APP_EXCEPTION", BUNDLE, message);
+            LOG.warning(errorMsg.toString());
         }
-         
-        Response r = ex.getResponse();
+        Response r = ex.getResponse(); 
         if (r == null) {
             String message = null;
             if (ex.getCause() == null) {

Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/tl/ThreadLocalMessageContext.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/tl/ThreadLocalMessageContext.java?rev=750522&r1=750521&r2=750522&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/tl/ThreadLocalMessageContext.java (original)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/tl/ThreadLocalMessageContext.java Thu Mar  5 17:52:17 2009
@@ -37,7 +37,7 @@
     public Object get(Object key) {
         return get() != null ? get().get(key) : null;
     }
-
+    
     public <T> T getContext(Class<T> contextClass) {
         return get() != null ? get().getContext(contextClass) : null;
     }
@@ -78,12 +78,11 @@
         return get() != null ? get().getRequest() : null;
     }
 
-    public void put(Object key, Object value, boolean outbound) {
+    public void put(Object key, Object value) {
         if (get() != null) {
-            get().put(key, value, outbound);
+            get().put(key, value);
         }
         throw new IllegalStateException("MessageContext is not set");
-        
     }
 
     public <T, E> T getResolver(Class<T> resolverClass, Class<E> resolveClazz) {

Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/interceptor/JAXRSInInterceptor.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/interceptor/JAXRSInInterceptor.java?rev=750522&r1=750521&r2=750522&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/interceptor/JAXRSInInterceptor.java (original)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/interceptor/JAXRSInInterceptor.java Thu Mar  5 17:52:17 2009
@@ -119,7 +119,7 @@
                 new org.apache.cxf.common.i18n.Message("NO_ROOT_EXC", 
                                                    BUNDLE, 
                                                    rawPath);
-            LOG.severe(errorMsg.toString());
+            LOG.warning(errorMsg.toString());
 
             throw new WebApplicationException(Response.Status.NOT_FOUND);
         }

Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/interceptor/JAXRSOutInterceptor.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/interceptor/JAXRSOutInterceptor.java?rev=750522&r1=750521&r2=750522&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/interceptor/JAXRSOutInterceptor.java (original)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/interceptor/JAXRSOutInterceptor.java Thu Mar  5 17:52:17 2009
@@ -25,6 +25,7 @@
 import java.lang.reflect.Method;
 import java.util.Collections;
 import java.util.List;
+import java.util.Map;
 import java.util.ResourceBundle;
 import java.util.logging.Logger;
 
@@ -32,21 +33,28 @@
 import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.Response;
 import javax.ws.rs.ext.MessageBodyWriter;
+import javax.xml.stream.XMLStreamWriter;
+import javax.xml.stream.events.XMLEvent;
 
 import org.apache.cxf.common.i18n.BundleUtils;
 import org.apache.cxf.common.logging.LogUtils;
+import org.apache.cxf.common.util.SystemUtils;
 import org.apache.cxf.interceptor.AbstractOutDatabindingInterceptor;
+import org.apache.cxf.io.CachedOutputStream;
 import org.apache.cxf.jaxrs.ext.ResponseHandler;
 import org.apache.cxf.jaxrs.model.ClassResourceInfo;
 import org.apache.cxf.jaxrs.model.OperationResourceInfo;
 import org.apache.cxf.jaxrs.model.ProviderInfo;
 import org.apache.cxf.jaxrs.provider.ProviderFactory;
 import org.apache.cxf.jaxrs.utils.HttpUtils;
+import org.apache.cxf.jaxrs.utils.InjectionUtils;
 import org.apache.cxf.jaxrs.utils.JAXRSUtils;
 import org.apache.cxf.message.Exchange;
 import org.apache.cxf.message.Message;
 import org.apache.cxf.message.MessageContentsList;
 import org.apache.cxf.phase.Phase;
+import org.apache.cxf.staxutils.CachingXmlEventWriter;
+import org.apache.cxf.staxutils.StaxUtils;
 
 public class JAXRSOutInterceptor extends AbstractOutDatabindingInterceptor {
     private static final Logger LOG = LogUtils.getL7dLogger(JAXRSOutInterceptor.class);
@@ -116,18 +124,27 @@
                                   String baseAddress,
                                   boolean firstTry) {
         message.put(Message.RESPONSE_CODE, response.getStatus());
-        message.put(Message.PROTOCOL_HEADERS, response.getMetadata());
-                        
+        Map<String, List<String>> theHeaders = 
+            (Map<String, List<String>>)message.get(Message.PROTOCOL_HEADERS);
+        if (firstTry && theHeaders != null) {
+            // some headers might've been setup by custom cxf interceptors
+            theHeaders.putAll((Map)response.getMetadata());
+        } else {
+            message.put(Message.PROTOCOL_HEADERS, response.getMetadata());
+        }
+        
         Object responseObj = response.getEntity();
         if (responseObj == null) {
             return;
         }
         
         Class targetType = responseObj.getClass();
-        List<MediaType> availableContentTypes = 
-            computeAvailableContentTypes(message, response);  
+        List<MediaType> availableContentTypes = computeAvailableContentTypes(message, response);  
         
-        Method invoked = ori == null ? null : ori.getMethodToInvoke();
+        Method invoked = null;
+        if (firstTry) {
+            invoked = ori == null ? null : ori.getMethodToInvoke();
+        }
         
         MessageBodyWriter writer = null;
         MediaType responseType = null;
@@ -137,7 +154,7 @@
                       invoked != null ? invoked.getGenericReturnType() : null, 
                       invoked != null ? invoked.getAnnotations() : new Annotation[]{}, 
                       type,
-                      message.getExchange().getInMessage());
+                      message);
             
             if (writer != null) {
                 responseType = type;
@@ -145,15 +162,13 @@
             }
         }
     
-        OutputStream out = message.getContent(OutputStream.class);
+        OutputStream outOriginal = message.getContent(OutputStream.class);
         if (writer == null) {
             message.put(Message.RESPONSE_CODE, 500);
-            writeResponseErrorMessage(out, 
-                  "NO_MSG_WRITER",
-                  invoked != null ? invoked.getReturnType().getSimpleName() : "");
+            writeResponseErrorMessage(outOriginal, "NO_MSG_WRITER", targetType.getSimpleName());
             return;
         }
-        
+        boolean enabled = checkBufferingMode(message, writer, firstTry);
         try {
             
             responseType = checkFinalContentType(responseType);
@@ -161,24 +176,79 @@
             message.put(Message.CONTENT_TYPE, responseType.toString());
             
             LOG.fine("Response EntityProvider is: " + writer.getClass().getName());
-            writer.writeTo(responseObj, targetType, invoked.getGenericReturnType(), 
-                           invoked != null ? invoked.getAnnotations() : new Annotation[]{}, 
-                           responseType, 
-                           response.getMetadata(), 
-                           out);
+            try {
+                writer.writeTo(responseObj, targetType, 
+                               invoked != null ? invoked.getGenericReturnType() : null, 
+                               invoked != null ? invoked.getAnnotations() : new Annotation[]{}, 
+                               responseType, 
+                               response.getMetadata(), 
+                               message.getContent(OutputStream.class));
+                checkCachedStream(message, outOriginal, enabled);
+            } finally {
+                if (enabled) {
+                    message.setContent(OutputStream.class, outOriginal);
+                    message.put(XMLStreamWriter.class.getName(), null);
+                }
+            }
             
         } catch (IOException ex) {
             handleWriteException(message, response, ori, baseAddress, ex, responseObj, firstTry);
-        } catch (Exception ex) {
+        } catch (Throwable ex) {
             handleWriteException(message, response, ori, baseAddress, ex, responseObj, firstTry);
         }
     }
     
+    private boolean checkBufferingMode(Message m, MessageBodyWriter w, boolean firstTry) {
+        if (!firstTry) {
+            return false;
+        }
+        boolean enabled = SystemUtils.isBufferingEnabled();
+        if (!enabled && !SystemUtils.isBufferingSet()) {
+            enabled = InjectionUtils.invokeBooleanGetter(w, "getEnableBuffering");
+        }
+        if (enabled) {
+            boolean streamingOn = 
+                "org.apache.cxf.jaxrs.provider.JAXBElementProvider".equals(w.getClass().getName())
+                && InjectionUtils.invokeBooleanGetter(w, "getEnableStreaming");
+            if (streamingOn) {
+                m.put(XMLStreamWriter.class.getName(), new CachingXmlEventWriter());
+            } else {
+                m.setContent(OutputStream.class, new CachedOutputStream());
+            }
+        }
+        return enabled;
+    }
+    
+    private void checkCachedStream(Message m, OutputStream osOriginal, boolean enabled) throws Exception {
+        if (!enabled) {
+            return;
+        }
+        XMLStreamWriter writer = (XMLStreamWriter)m.get(XMLStreamWriter.class.getName());
+        if (writer instanceof CachingXmlEventWriter) {
+            CachingXmlEventWriter cache = (CachingXmlEventWriter)writer;
+            if (cache.getEvents().size() != 0) {
+                XMLStreamWriter origWriter = StaxUtils.createXMLStreamWriter(osOriginal);
+                for (XMLEvent event : cache.getEvents()) {
+                    StaxUtils.writeEvent(event, origWriter);
+                }
+            }
+            m.put(XMLStreamWriter.class.getName(), null);
+            return;
+        }
+        OutputStream os = m.getContent(OutputStream.class);
+        if (os != osOriginal && os instanceof CachedOutputStream) {
+            CachedOutputStream cos = (CachedOutputStream)os;
+            if (cos.size() != 0) {
+                cos.writeCacheTo(osOriginal);
+            }
+        }
+    }
+    
     private void handleWriteException(Message message, 
                                          Response response, 
                                          OperationResourceInfo ori,
                                          String baseAddress,
-                                         Exception ex,
+                                         Throwable ex,
                                          Object responseObj,
                                          boolean firstTry) {
         OutputStream out = message.getContent(OutputStream.class);
@@ -218,7 +288,7 @@
         List<MediaType> produceTypes = null;
         OperationResourceInfo operation = exchange.get(OperationResourceInfo.class);
         if (contentType != null) {
-            produceTypes = Collections.singletonList(MediaType.valueOf(contentType.toString()));
+            return Collections.singletonList(MediaType.valueOf(contentType.toString()));
         } else if (operation != null) {
             produceTypes = operation.getProduceTypes();
         } else {

Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/AbstractConfigurableProvider.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/AbstractConfigurableProvider.java?rev=750522&r1=750521&r2=750522&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/AbstractConfigurableProvider.java (original)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/AbstractConfigurableProvider.java Thu Mar  5 17:52:17 2009
@@ -25,8 +25,9 @@
 
     private List<String> consumeMediaTypes;
     private List<String> produceMediaTypes;
+    private boolean enableBuffering;
     
-    protected void setConsumeMediaTypes(List<String> types) {
+    public void setConsumeMediaTypes(List<String> types) {
         consumeMediaTypes = types;
     }
     
@@ -34,11 +35,19 @@
         return consumeMediaTypes;    
     }
     
-    protected void setProduceMediaTypes(List<String> types) {
+    public void setProduceMediaTypes(List<String> types) {
         produceMediaTypes = types;
     }
     
     public List<String> getProduceMediaTypes() {
         return produceMediaTypes;    
     }
+    
+    public void setEnableBuffering(boolean enableBuf) {
+        enableBuffering = enableBuf;
+    }
+    
+    public boolean getEnableBuffering() {
+        return enableBuffering;
+    }
 }

Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/AbstractJAXBProvider.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/AbstractJAXBProvider.java?rev=750522&r1=750521&r2=750522&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/AbstractJAXBProvider.java (original)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/AbstractJAXBProvider.java Thu Mar  5 17:52:17 2009
@@ -64,7 +64,7 @@
    
     private MessageContext mc;
     private Schema schema;
-            
+    
     protected void setContext(MessageContext context) {
         mc = context;
     }
@@ -160,7 +160,6 @@
         // TODO: still not checked : 
         // - XmlJavaTypeAdapter at package level
         // - anything else ?
-        
         return type.getAnnotation(XmlRootElement.class) != null
             || JAXBElement.class.isAssignableFrom(type)
             || objectFactoryForClass(type)
@@ -276,6 +275,7 @@
             ? e.getLinkedException() : e.getCause() != null ? e.getCause() : e;
         String message = new org.apache.cxf.common.i18n.Message("JAXB_EXCEPTION", 
                              BUNDLE, t.getMessage()).toString();
+        LOG.warning(message);
         Response r = Response.status(Response.Status.INTERNAL_SERVER_ERROR)
             .type(MediaType.TEXT_PLAIN).entity(message).build();
         throw new WebApplicationException(t, r);

Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/BinaryDataProvider.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/BinaryDataProvider.java?rev=750522&r1=750521&r2=750522&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/BinaryDataProvider.java (original)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/BinaryDataProvider.java Thu Mar  5 17:52:17 2009
@@ -40,7 +40,7 @@
 
 import org.apache.cxf.helpers.IOUtils;
 
-public class BinaryDataProvider 
+public class BinaryDataProvider extends AbstractConfigurableProvider 
     implements MessageBodyReader<Object>, MessageBodyWriter<Object> {
     
     private static final int BUFFER_SIZE = 4096;

Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/JAXBElementProvider.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/JAXBElementProvider.java?rev=750522&r1=750521&r2=750522&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/JAXBElementProvider.java (original)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/JAXBElementProvider.java Thu Mar  5 17:52:17 2009
@@ -39,10 +39,12 @@
 import javax.xml.bind.JAXBException;
 import javax.xml.bind.Marshaller;
 import javax.xml.bind.Unmarshaller;
+import javax.xml.stream.XMLStreamWriter;
 import javax.xml.transform.stream.StreamSource;
 
 import org.apache.cxf.jaxrs.ext.MessageContext;
 import org.apache.cxf.jaxrs.utils.schemas.SchemaHandler;
+import org.apache.cxf.staxutils.StaxUtils;
 
 @Produces({"application/xml", "text/xml" })
 @Consumes({"application/xml", "text/xml" })
@@ -50,12 +52,25 @@
 public class JAXBElementProvider extends AbstractJAXBProvider  {
     
     private Map<String, Object> mProperties = new HashMap<String, Object>();
+    private boolean enableStreaming;
     
     @Context
     public void setMessageContext(MessageContext mc) {
         super.setContext(mc);
     }
     
+    public void setEnableStreaming(boolean enableStream) {
+        enableStreaming = enableStream; 
+    }
+    
+    public boolean getEnableStreaming() {
+        return enableStreaming;
+    }
+    
+    public void setEnableBuffering(boolean enableBuf) {
+        super.setEnableBuffering(enableBuf);
+    }
+    
     public void setConsumeMediaTypes(List<String> types) {
         super.setConsumeMediaTypes(types);
     }
@@ -121,10 +136,19 @@
             for (Map.Entry<String, Object> entry : mProperties.entrySet()) {
                 ms.setProperty(entry.getKey(), entry.getValue());
             }
-            ms.marshal(actualObject, os);
+            if (enableStreaming) {
+                XMLStreamWriter writer = 
+                    (XMLStreamWriter)getContext().get(XMLStreamWriter.class.getName());
+                if (writer == null) {
+                    writer = StaxUtils.createXMLStreamWriter(os);
+                }
+                ms.marshal(actualObject, writer);
+            } else {
+                ms.marshal(actualObject, os);
+            }
             
         } catch (JAXBException e) {
-            throw new WebApplicationException(e);
+            handleJAXBException(e);
         }  catch (WebApplicationException e) {
             throw e;
         } catch (Exception e) {

Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/JSONProvider.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/JSONProvider.java?rev=750522&r1=750521&r2=750522&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/JSONProvider.java (original)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/JSONProvider.java Thu Mar  5 17:52:17 2009
@@ -70,6 +70,10 @@
         super.setContext(mc);
     }
     
+    public void setEnableBuffering(boolean enableBuf) {
+        super.setEnableBuffering(enableBuf);
+    }
+    
     public void setConsumeMediaTypes(List<String> types) {
         super.setConsumeMediaTypes(types);
     }
@@ -163,7 +167,7 @@
             xsw.close();
             
         } catch (JAXBException e) {
-            throw new WebApplicationException(e);
+            handleJAXBException(e);
         } catch (XMLStreamException e) {
             throw new WebApplicationException(e);
         } catch (Exception e) {

Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/SourceProvider.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/SourceProvider.java?rev=750522&r1=750521&r2=750522&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/SourceProvider.java (original)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/SourceProvider.java Thu Mar  5 17:52:17 2009
@@ -25,6 +25,8 @@
 import java.lang.annotation.Annotation;
 import java.lang.reflect.Type;
 
+import javax.ws.rs.Consumes;
+import javax.ws.rs.Produces;
 import javax.ws.rs.WebApplicationException;
 import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.MultivaluedMap;
@@ -44,6 +46,8 @@
 import org.w3c.dom.Document;
 
 @Provider
+@Produces({"application/xml", "text/xml" })
+@Consumes({"application/xml", "text/xml" })
 public class SourceProvider implements 
     MessageBodyReader<Object>, MessageBodyWriter<Source> {
 

Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/InjectionUtils.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/InjectionUtils.java?rev=750522&r1=750521&r2=750522&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/InjectionUtils.java (original)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/InjectionUtils.java Thu Mar  5 17:52:17 2009
@@ -87,6 +87,16 @@
         
     }
 
+    public static boolean invokeBooleanGetter(Object o, String name) {
+        try {
+            Method method = o.getClass().getMethod(name, new Class[]{});
+            return (Boolean)method.invoke(o, new Object[]{});
+        } catch (Exception ex) {
+            LOG.finest("Can not invoke method " + name + " on object of class " + o.getClass().getName());
+        }
+        return false;
+    }
+    
     public static Method checkProxy(Method methodToInvoke, Object resourceObject) {
         if (Proxy.class.isInstance(resourceObject)) {
             for (Class<?> c : resourceObject.getClass().getInterfaces()) {

Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/JAXRSUtils.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/JAXRSUtils.java?rev=750522&r1=750521&r2=750522&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/JAXRSUtils.java (original)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/JAXRSUtils.java Thu Mar  5 17:52:17 2009
@@ -303,7 +303,7 @@
                                                    path,
                                                    requestType.toString(),
                                                    convertTypesToString(acceptContentTypes));
-        LOG.severe(errorMsg.toString());
+        LOG.warning(errorMsg.toString());
         
         throw new WebApplicationException(status);
         
@@ -630,24 +630,25 @@
     
     public static <T> T createContextValue(Message m, Type genericType, Class<T> clazz) {
  
+        Message inbound = m.getExchange() != null ? m.getExchange().getInMessage() : m;
         Object o = null;
         if (UriInfo.class.isAssignableFrom(clazz)) {
-            o = createUriInfo(m);
+            o = createUriInfo(inbound);
         } else if (HttpHeaders.class.isAssignableFrom(clazz)) {
-            o = new HttpHeadersImpl(m);
+            o = new HttpHeadersImpl(inbound);
         } else if (Request.class.isAssignableFrom(clazz)) {
-            o = new RequestImpl(m);
+            o = new RequestImpl(inbound);
         } else if (SecurityContext.class.isAssignableFrom(clazz)) {
-            o = new SecurityContextImpl(m);
+            o = new SecurityContextImpl(inbound);
         } else if (Providers.class.isAssignableFrom(clazz)) {
-            o = new ProvidersImpl(m);
+            o = new ProvidersImpl(inbound);
         } else if (ContextResolver.class.isAssignableFrom(clazz)) {
-            o = createContextResolver(genericType, m);
+            o = createContextResolver(genericType, inbound);
         } else if (MessageContext.class.isAssignableFrom(clazz)) {
             o = new MessageContextImpl(m);
         }
         
-        o = o == null ? createServletResourceValue(m, clazz) : o;
+        o = o == null ? createServletResourceValue(inbound, clazz) : o;
         return clazz.cast(o);
     }
     
@@ -809,14 +810,18 @@
                                           + targetTypeClass.getSimpleName() 
                                            + ", content type : " + contentType;
                     LOG.severe(errorMessage);
-                    throw new WebApplicationException(Response.Status.INTERNAL_SERVER_ERROR);
-                }    
+                    throw new WebApplicationException(e);
+                } catch (WebApplicationException ex) {
+                    throw ex;
+                } catch (Exception ex) {
+                    throw new WebApplicationException(ex);
+                }
             } else {
                 String errorMessage = new org.apache.cxf.common.i18n.Message("NO_MSG_READER",
                                                        BUNDLE,
                                                        targetTypeClass.getSimpleName(),
                                                        contentType).toString();
-                LOG.severe(errorMessage);
+                LOG.warning(errorMessage);
                 throw new WebApplicationException(Response.Status.UNSUPPORTED_MEDIA_TYPE);
             }
         }

Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/multipart/AttachmentUtils.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/multipart/AttachmentUtils.java?rev=750522&r1=750521&r2=750522&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/multipart/AttachmentUtils.java (original)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/multipart/AttachmentUtils.java Thu Mar  5 17:52:17 2009
@@ -73,10 +73,10 @@
     public static MultipartBody getMultipartBody(MessageContext mc,
         String attachmentDir, String attachmentThreshold) {
         if (attachmentDir != null) {
-            mc.put(AttachmentDeserializer.ATTACHMENT_DIRECTORY, attachmentDir, false);
+            mc.put(AttachmentDeserializer.ATTACHMENT_DIRECTORY, attachmentDir);
         }
         if (attachmentThreshold != null) {
-            mc.put(AttachmentDeserializer.ATTACHMENT_MEMORY_THRESHOLD, attachmentThreshold, false);
+            mc.put(AttachmentDeserializer.ATTACHMENT_MEMORY_THRESHOLD, attachmentThreshold);
         }
         return (MultipartBody)mc.get(MultipartBody.INBOUND_MESSAGE_ATTACHMENTS);
     }

Modified: cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/provider/ProviderFactoryTest.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/provider/ProviderFactoryTest.java?rev=750522&r1=750521&r2=750522&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/provider/ProviderFactoryTest.java (original)
+++ cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/provider/ProviderFactoryTest.java Thu Mar  5 17:52:17 2009
@@ -193,11 +193,11 @@
         MediaType mType = MediaType.valueOf(mediaType);
         
         MessageBodyReader reader = ProviderFactory.getInstance()
-            .createMessageBodyReader(type, null, null, mType, null);
+            .createMessageBodyReader(type, null, null, mType, new MessageImpl());
         assertSame(errorMessage, provider, reader.getClass());
     
         MessageBodyWriter writer = ProviderFactory.getInstance()
-            .createMessageBodyWriter(type, null, null, mType, null);
+            .createMessageBodyWriter(type, null, null, mType, new MessageImpl());
         assertTrue(errorMessage, provider == writer.getClass());
     }
     

Modified: cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/BookServer.java
URL: http://svn.apache.org/viewvc/cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/BookServer.java?rev=750522&r1=750521&r2=750522&view=diff
==============================================================================
--- cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/BookServer.java (original)
+++ cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/BookServer.java Thu Mar  5 17:52:17 2009
@@ -19,8 +19,14 @@
 
 package org.apache.cxf.systest.jaxrs;
 
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.cxf.interceptor.Interceptor;
 import org.apache.cxf.jaxrs.JAXRSServerFactoryBean;
 import org.apache.cxf.jaxrs.lifecycle.SingletonResourceProvider;
+import org.apache.cxf.jaxrs.provider.BinaryDataProvider;
 import org.apache.cxf.testutil.common.AbstractBusTestServerBase;
     
 public class BookServer extends AbstractBusTestServerBase {
@@ -29,6 +35,13 @@
         JAXRSServerFactoryBean sf = new JAXRSServerFactoryBean();
         sf.setResourceClasses(BookStore.class);
         //default lifecycle is per-request, change it to singleton
+        BinaryDataProvider p = new BinaryDataProvider();
+        p.setProduceMediaTypes(Collections.singletonList("application/bar"));
+        p.setEnableBuffering(true);
+        sf.setProvider(p);
+        List<Interceptor> ints = new ArrayList<Interceptor>();
+        ints.add(new CustomOutInterceptor());
+        sf.setOutInterceptors(ints);
         sf.setResourceProvider(BookStore.class,
                                new SingletonResourceProvider(new BookStore()));
         sf.setAddress("http://localhost:9080/");

Modified: cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/BookStore.java
URL: http://svn.apache.org/viewvc/cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/BookStore.java?rev=750522&r1=750521&r2=750522&view=diff
==============================================================================
--- cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/BookStore.java (original)
+++ cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/BookStore.java Thu Mar  5 17:52:17 2009
@@ -21,6 +21,7 @@
 
 
 import java.io.IOException;
+import java.io.InputStream;
 import java.io.OutputStream;
 import java.net.URL;
 import java.util.Calendar;
@@ -265,11 +266,26 @@
         return doGetBook(currentBookId);
     }
     
+    
     @GET
-    @Path("/books/stream")
-    @Produces("application/xml")
+    @Path("/books/buffer")
+    @Produces("application/bar")
+    public InputStream getBufferedBook() {
+        return getClass().getResourceAsStream("resources/expected_get_book123.txt");
+    }
+    
+    @GET
+    @Path("/books/fail-early")
+    @Produces("application/bar")
+    public StreamingOutput failEarlyInWrite() {
+        return new StreamingOutputImpl(true);
+    }
+    
+    @GET
+    @Path("/books/fail-late")
+    @Produces("application/bar")
     public StreamingOutput writeToStreamAndFail() {
-        return new StreamingOutputImpl();
+        return new StreamingOutputImpl(false);
     }
     
     private Book doGetBook(String id) throws BookNotFoundFault {
@@ -523,11 +539,21 @@
     
     private static class StreamingOutputImpl implements StreamingOutput {
 
+        private boolean failEarly;
+        
+        public StreamingOutputImpl(boolean failEarly) {
+            this.failEarly = failEarly;
+        }
+        
         public void write(OutputStream output) throws IOException, WebApplicationException {
-            //output.write("This is not supposed to go on the wire".getBytes());
-            throw new WebApplicationException(
-                 Response.status(410).type("text/plain")
-                 .entity("This is supposed to go on the wire").build());
+            if (failEarly) {
+                throw new WebApplicationException(
+                     Response.status(410).type("text/plain")
+                     .entity("This is supposed to go on the wire").build());
+            } else {
+                output.write("This is not supposed to go on the wire".getBytes());
+                throw new WebApplicationException(410);
+            }
         } 
         
     }

Added: cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/CustomOutInterceptor.java
URL: http://svn.apache.org/viewvc/cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/CustomOutInterceptor.java?rev=750522&view=auto
==============================================================================
--- cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/CustomOutInterceptor.java (added)
+++ cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/CustomOutInterceptor.java Thu Mar  5 17:52:17 2009
@@ -0,0 +1,41 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cxf.systest.jaxrs;
+
+import javax.ws.rs.core.MultivaluedMap;
+
+import org.apache.cxf.interceptor.Fault;
+import org.apache.cxf.jaxrs.impl.MetadataMap;
+import org.apache.cxf.message.Message;
+import org.apache.cxf.phase.AbstractPhaseInterceptor;
+import org.apache.cxf.phase.Phase;
+
+public class CustomOutInterceptor extends AbstractPhaseInterceptor<Message> {
+
+    public CustomOutInterceptor() {
+        super(Phase.MARSHAL);
+    }
+
+    public void handleMessage(Message message) throws Fault {
+        MultivaluedMap<String, Object> headers = new MetadataMap<String, Object>();
+        headers.putSingle("BookId", "123");
+        message.put(Message.PROTOCOL_HEADERS, headers);
+    }
+
+}

Propchange: cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/CustomOutInterceptor.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/CustomOutInterceptor.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Modified: cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerBookTest.java
URL: http://svn.apache.org/viewvc/cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerBookTest.java?rev=750522&r1=750521&r2=750522&view=diff
==============================================================================
--- cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerBookTest.java (original)
+++ cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerBookTest.java Thu Mar  5 17:52:17 2009
@@ -86,9 +86,15 @@
     
     @Test
     public void testWriteAndFailEarly() throws Exception {
-        getAndCompare("http://localhost:9080/bookstore/books/stream",
+        getAndCompare("http://localhost:9080/bookstore/books/fail-early",
                       "This is supposed to go on the wire",
-                      "application/xml, text/plain", 410);
+                      "application/bar, text/plain", 410);
+    }
+    
+    @Test
+    public void testWriteAndFailLate() throws Exception {
+        getAndCompare("http://localhost:9080/bookstore/books/fail-late",
+                      "", "application/bar", 410);
     }
     
     
@@ -257,6 +263,13 @@
     }
     
     @Test
+    public void testGetBookBuffer() throws Exception {
+        getAndCompareAsStrings("http://localhost:9080/bookstore/books/buffer",
+                               "resources/expected_get_book123.txt",
+                               "application/bar", 200);
+    }    
+    
+    @Test
     public void testGetBookBySegment() throws Exception {
         getAndCompareAsStrings("http://localhost:9080/bookstore/segment/matrix2;first=12;second=3",
                                "resources/expected_get_book123.txt",
@@ -728,6 +741,9 @@
             String content = getStringFromInputStream(get.getResponseBodyAsStream());
             assertEquals("Expected value is wrong", 
                          expectedValue, content);
+            if (expectedStatus == 200) {
+                assertEquals("123", get.getResponseHeader("BookId").getValue());
+            }
         } finally {
             get.releaseConnection();
         }

Added: cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerStreamingTest.java
URL: http://svn.apache.org/viewvc/cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerStreamingTest.java?rev=750522&view=auto
==============================================================================
--- cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerStreamingTest.java (added)
+++ cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerStreamingTest.java Thu Mar  5 17:52:17 2009
@@ -0,0 +1,106 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.cxf.systest.jaxrs;
+
+import java.io.InputStream;
+
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.Unmarshaller;
+
+import org.apache.commons.httpclient.HttpClient;
+import org.apache.commons.httpclient.methods.GetMethod;
+import org.apache.cxf.jaxrs.JAXRSServerFactoryBean;
+import org.apache.cxf.jaxrs.lifecycle.SingletonResourceProvider;
+import org.apache.cxf.jaxrs.provider.JAXBElementProvider;
+import org.apache.cxf.testutil.common.AbstractBusClientServerTestBase;
+import org.apache.cxf.testutil.common.AbstractBusTestServerBase;
+
+import org.junit.BeforeClass;
+import org.junit.Ignore;
+import org.junit.Test;
+
+public class JAXRSClientServerStreamingTest extends AbstractBusClientServerTestBase {
+
+    @Ignore
+    public static class Server extends AbstractBusTestServerBase {        
+
+        protected void run() {
+            JAXRSServerFactoryBean sf = new JAXRSServerFactoryBean();
+            sf.setResourceClasses(BookStore.class);
+            sf.setResourceProvider(BookStore.class,
+                                   new SingletonResourceProvider(new BookStore()));
+            JAXBElementProvider p = new JAXBElementProvider();
+            p.setEnableBuffering(true);
+            p.setEnableStreaming(true);
+            sf.setProvider(p);
+            sf.setAddress("http://localhost:9080/");
+
+            sf.create();
+
+        }
+
+        public static void main(String[] args) {
+            try {
+                Server s = new Server();
+                s.start();
+            } catch (Exception ex) {
+                ex.printStackTrace();
+                System.exit(-1);
+            } finally {
+                System.out.println("done!");
+            }
+        }
+    }
+    
+    @BeforeClass
+    public static void startServers() throws Exception {
+        assertTrue("server did not launch correctly",
+                   launchServer(Server.class));
+    }
+    
+    @Test
+    public void testGetBook123() throws Exception {
+        getAndCompare("http://localhost:9080/bookstore/books/123",
+                      "application/xml", 200);
+    }
+    
+    private void getAndCompare(String address, 
+                               String acceptType,
+                               int expectedStatus) throws Exception {
+        GetMethod get = new GetMethod(address);
+        get.setRequestHeader("Accept", acceptType);
+        HttpClient httpClient = new HttpClient();
+        try {
+            int result = httpClient.executeMethod(get);
+            assertEquals(expectedStatus, result);
+            Book book = readBook(get.getResponseBodyAsStream());
+            assertEquals(123, book.getId());
+            assertEquals("CXF in Action", book.getName());
+        } finally {
+            get.releaseConnection();
+        }
+    }
+    
+    private Book readBook(InputStream is) throws Exception {
+        JAXBContext c = JAXBContext.newInstance(new Class[]{Book.class});
+        Unmarshaller u = c.createUnmarshaller();
+        return (Book)u.unmarshal(is);
+    }
+}

Propchange: cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerStreamingTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerStreamingTest.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date



RE: ProviderFactory singleton?

Posted by "Tong, Gary (IDEAS)" <Ga...@morganstanley.com>.
I guess I just find that conceptually awkward.

Our use case is that we have a single war that hosts a variety of CXF services imported from module jars.  Each module is responsible for defining their own CXF server, and the war creates one CXF servlet for each module and places each one on their own context path.  The war also makes certain common services available to each module via spring, which allows common singleton-type objects to be shared across multiple modules (things like datasources, caches, threadpools, etc)

Each module has no knowledge of any other module its deployed next to, which is why multiple modules may easily have overlapping addresses.  We first came upon this issue when different modules defined different error handlers, which worked in each module independently, but broke when deployed.

As a spring-based application, I suppose the assumption is that any singletons in the system would be spring-style singletons, isolated at the bean factory level.

Not a show-stopper for us, but since JAX-RS is a very nice easy-to-use library, as usage spreads I wouldn't be surprised if this issue comes up again as CXF JAX-RS is deployed into wierder and wierder containers.  An OSGi container with shared classloading comes to mind as an environment where this would break.

-----Original Message-----
From: Sergey Beryozkin [mailto:sberyozk@progress.com]
Sent: 06 March 2009 12:13
To: dev@cxf.apache.org
Subject: RE: ProviderFactory singleton?

OK. I'm not sure yet what would be the best way to tackle it.
How restrictive would it be if we said that every jaxrs:endpoint should have its own unique address ?

For ex, at the moment :

CXFServlet1 : /1/* links to beans1.xml
CXFServlet2 : /2/* links to beans2.xml

jaxrs:server/@adress='/' in both beans1.xml and beans2.xml, presumably relying on separate resource classes, say the one in beans1.xml uses Resource.class with @Path("/r1") and the other one uses Resource2.class with @Path("/r2")

So one option would be to move /r1 and /r2 out of the resource classes into corresponding jaxrs:server/@adress(es) and just have @Path("/") for both resource classes.

One issue is that ProviderFactory is also used at the moment in the client api, 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.Tong@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:sberyozk@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.Tong@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.

--------------------------------------------------------------------------
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.

Re: ProviderFactory singleton?

Posted by Sergey Beryozkin <sb...@progress.com>.
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" <sb...@progress.com>
To: <de...@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)" <Ga...@morganstanley.com>
> To: "'Daniel Kulp'" <dk...@apache.org>; <de...@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:dkulp@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:sberyozk@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.Tong@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:sberyozk@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.Tong@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
>> > dkulp@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
> dkulp@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. 


Re: ProviderFactory singleton?

Posted by Sergey Beryozkin <sb...@progress.com>.
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)" <Ga...@morganstanley.com>
To: "'Daniel Kulp'" <dk...@apache.org>; <de...@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:dkulp@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:sberyozk@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.Tong@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:sberyozk@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.Tong@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
> > dkulp@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
dkulp@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. 


RE: ProviderFactory singleton?

Posted by "Tong, Gary (IDEAS)" <Ga...@morganstanley.com>.
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:dkulp@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:sberyozk@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.Tong@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:sberyozk@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.Tong@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
> > dkulp@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
dkulp@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.

Re: ProviderFactory singleton?

Posted by Daniel Kulp <dk...@apache.org>.
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:sberyozk@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.Tong@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:sberyozk@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.Tong@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
> > dkulp@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
dkulp@apache.org
http://www.dankulp.com/blog

Re: ProviderFactory singleton?

Posted by Sergey Beryozkin <sb...@progress.com>.
Hi Gary

is there any chance you can share it somehow ? Perhaps opening a JIRA and attaching some sample configuration or indeed, juts 
posting it to the list ? It will make it easier for me to start working on a fix..

Cheers, Sergey


----- Original Message ----- 
From: "Tong, Gary (IDEAS)" <Ga...@morganstanley.com>
To: <de...@cxf.apache.org>; "Daniel Kulp" <dk...@apache.org>
Sent: Monday, March 09, 2009 10:54 AM
Subject: RE: ProviderFactory singleton?


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:sberyozk@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.Tong@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:sberyozk@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.Tong@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
> dkulp@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. 


RE: ProviderFactory singleton?

Posted by "Tong, Gary (IDEAS)" <Ga...@morganstanley.com>.
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:sberyozk@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.Tong@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:sberyozk@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.Tong@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
> dkulp@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.

Re: ProviderFactory singleton?

Posted by Sergey Beryozkin <sb...@progress.com>.
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.Tong@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:sberyozk@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.Tong@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
> dkulp@apache.org
> http://www.dankulp.com/blog

Re: ProviderFactory singleton?

Posted by Daniel Kulp <dk...@apache.org>.
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.Tong@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:sberyozk@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.Tong@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
dkulp@apache.org
http://www.dankulp.com/blog

RE: ProviderFactory singleton?

Posted by Sergey Beryozkin <sb...@progress.com>.
OK. I'm not sure yet what would be the best way to tackle it.
How restrictive would it be if we said that every jaxrs:endpoint should
have its own unique address ? 

For ex, at the moment :

CXFServlet1 : /1/* links to beans1.xml 
CXFServlet2 : /2/* links to beans2.xml

jaxrs:server/@adress='/' in both beans1.xml and beans2.xml,
presumably relying on separate resource classes, say the one in
beans1.xml uses Resource.class with @Path("/r1") and the other one uses
Resource2.class with @Path("/r2")  

So one option would be to move /r1 and /r2 out of the resource classes
into corresponding jaxrs:server/@adress(es) and just have @Path("/") for
both resource classes.

One issue is that ProviderFactory is also used at the moment in the
client api, 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.Tong@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:sberyozk@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.Tong@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.

RE: ProviderFactory singleton?

Posted by "Tong, Gary (IDEAS)" <Ga...@morganstanley.com>.
> Is it when you have multiple CXF servlets, each of them referencing different spring configuration files ?

Yes exactly.

-----Original Message-----
From: Sergey Beryozkin [mailto:sberyozk@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.Tong@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.

RE: ProviderFactory singleton?

Posted by Sergey Beryozkin <sb...@progress.com>.
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.Tong@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.

ProviderFactory singleton?

Posted by "Tong, Gary (IDEAS)" <Ga...@morganstanley.com>.
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.

Re: svn commit: r750522 -

Posted by Daniel Kulp <dk...@apache.org>.
On Thu March 5 2009 2:36:55 pm Sergey Beryozkin wrote:
> ok, I guess I misinterpreted the original hint. I'll get back to it
> tomorrow as I'm off now, will update the AbstractOutDatabindingInterceptor
> to check the message instead...
>
> By the way, what is the key idea behind the message contextual property as
> opposed to a plain message property (set on the inbound/outbound message).
> When such a contextual property is supposed to be set ? Is it when say
> properties on a jaxws:endpoint are configured ?

The contextual property check a hiearchy of places.   The Message is first, so 
anything set on the message overrides anything else.   I think the exchange is 
next, then the service, then the endpoint.   I plan on adding a properties 
thing to the Bus as well and making that last (to allow Bus scoped 
properties), just haven't gotten around to it.  

The main thing this allows is configuring things at various levels.  For 
example, take MTOM.    You can configure it in spring config which would put 
it at a endpoint level.   However, an interceptor could override it by setting 
it on the message.   That changes the behavior for that invokation, but not 
all invokations.  

Dan


>
>
> Cheers, Sergey
>
> ----- Original Message -----
> From: "Daniel Kulp" <dk...@apache.org>
> To: <de...@cxf.apache.org>
> Sent: Thursday, March 05, 2009 6:39 PM
> Subject: Re: svn commit: r750522 - in /cxf/trunk:
> common/common/src/main/java/org/apache/cxf/common/util/
> rt/core/src/main/java/org/apache/cxf/bus/spring/
> rt/core/src/main/java/org/apache/cxf/interceptor/
> rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/ rt...
>
> On Thu March 5 2009 12:52:21 pm sergeyb@apache.org wrote:
> > CachingXmlEventWriter cache = null;
> >
> > - if (shouldValidate(message) && !isRequestor(message)) {
> > - //need to cache the events in case validation fails
> > + // need to cache the events in case validation fails or buffering
> > is enabled + if (shouldValidate(message) && !isRequestor(message)
> > + || SystemUtils.isBufferingEnabled()) {
> > cache = new CachingXmlEventWriter();
> > try {
>
> This definitely shouldn't be based on a system property.   It should be
> something like:
>
> message.getContextualProperty("org.apache.cxf.buffer.output")
>
> or similar so it can be configured on a per-endpoint basis.

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

Re: svn commit: r750522 -

Posted by Sergey Beryozkin <sb...@progress.com>.
ok, I guess I misinterpreted the original hint. I'll get back to it tomorrow as I'm off now, will update the 
AbstractOutDatabindingInterceptor to check the message instead...

By the way, what is the key idea behind the message contextual property as opposed to a plain message property (set on the 
inbound/outbound message). When such a contextual property is supposed to be set ? Is it when say properties on a jaxws:endpoint are 
configured ?


Cheers, Sergey

----- Original Message ----- 
From: "Daniel Kulp" <dk...@apache.org>
To: <de...@cxf.apache.org>
Sent: Thursday, March 05, 2009 6:39 PM
Subject: Re: svn commit: r750522 - in /cxf/trunk: common/common/src/main/java/org/apache/cxf/common/util/ 
rt/core/src/main/java/org/apache/cxf/bus/spring/ rt/core/src/main/java/org/apache/cxf/interceptor/ 
rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/ rt...


On Thu March 5 2009 12:52:21 pm sergeyb@apache.org wrote:
> CachingXmlEventWriter cache = null;
>
> - if (shouldValidate(message) && !isRequestor(message)) {
> - //need to cache the events in case validation fails
> + // need to cache the events in case validation fails or buffering
> is enabled + if (shouldValidate(message) && !isRequestor(message)
> + || SystemUtils.isBufferingEnabled()) {
> cache = new CachingXmlEventWriter();
> try {

This definitely shouldn't be based on a system property.   It should be
something like:

message.getContextualProperty("org.apache.cxf.buffer.output")

or similar so it can be configured on a per-endpoint basis.


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


Re: svn commit: r750522 - in /cxf/trunk: common/common/src/main/java/org/apache/cxf/common/util/ rt/core/src/main/java/org/apache/cxf/bus/spring/ rt/core/src/main/java/org/apache/cxf/interceptor/ rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/ rt...

Posted by Daniel Kulp <dk...@apache.org>.
On Thu March 5 2009 12:52:21 pm sergeyb@apache.org wrote:
>          CachingXmlEventWriter cache = null;
>          
> -        if (shouldValidate(message) && !isRequestor(message)) {
> -            //need to cache the events in case validation fails
> +        // need to cache the events in case validation fails or buffering
> is enabled +        if (shouldValidate(message) && !isRequestor(message)
> +            || SystemUtils.isBufferingEnabled()) {
>              cache = new CachingXmlEventWriter();
>              try {

This definitely shouldn't be based on a system property.   It should be 
something like:

message.getContextualProperty("org.apache.cxf.buffer.output")

or similar so it can be configured on a per-endpoint basis.


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