Author: ningjiang
Date: Fri Dec 10 11:46:00 2010
New Revision: 1044309
URL: http://svn.apache.org/viewvc?rev=1044309&view=rev
Log:
Merged revisions 1044238,1044305 via svnmerge from
https://svn.apache.org/repos/asf/cxf/trunk
........
r1044238 | ningjiang | 2010-12-10 16:04:00 +0800 (Fri, 10 Dec 2010) | 1 line
CXF-3180 try to fix the Jaxrs/Jaxb unmarshaller code regularly causing
performance problems & thread lock-up
........
r1044305 | ningjiang | 2010-12-10 19:40:30 +0800 (Fri, 10 Dec 2010) | 1 line
CXF-3180 removed the synchronized part of JAXBMarshallerUnmarshallerCache as
it is used per thread
........
Modified:
cxf/branches/2.3.x-fixes/ (props changed)
cxf/branches/2.3.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/AbstractJAXBProvider.java
cxf/branches/2.3.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/JAXBElementProvider.java
Propchange: cxf/branches/2.3.x-fixes/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Fri Dec 10 11:46:00 2010
@@ -1 +1 @@
-/cxf/trunk:1041183,1041790,1041993,1042346,1042571,1042724,1042805,1042821,1043225,1043229,1043902,1043907,1043954,1044085
+/cxf/trunk:1041183,1041790,1041993,1042346,1042571,1042724,1042805,1042821,1043225,1043229,1043902,1043907,1043954,1044085,1044238-1044305
Propchange: cxf/branches/2.3.x-fixes/
------------------------------------------------------------------------------
Binary property 'svnmerge-integrated' - no diff available.
Modified:
cxf/branches/2.3.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/AbstractJAXBProvider.java
URL:
http://svn.apache.org/viewvc/cxf/branches/2.3.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/AbstractJAXBProvider.java?rev=1044309&r1=1044308&r2=1044309&view=diff
==============================================================================
---
cxf/branches/2.3.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/AbstractJAXBProvider.java
(original)
+++
cxf/branches/2.3.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/AbstractJAXBProvider.java
Fri Dec 10 11:46:00 2010
@@ -24,6 +24,7 @@ import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.lang.annotation.Annotation;
+import java.lang.ref.SoftReference;
import java.lang.reflect.Array;
import java.lang.reflect.Type;
import java.util.ArrayList;
@@ -91,7 +92,6 @@ public abstract class AbstractJAXBProvid
private static Map<String, JAXBContext> packageContexts = new
HashMap<String, JAXBContext>();
private static Map<Class<?>, JAXBContext> classContexts = new
HashMap<Class<?>, JAXBContext>();
-
protected Set<Class<?>> collectionContextClasses = new HashSet<Class<?>>();
protected JAXBContext collectionContext;
@@ -106,6 +106,8 @@ public abstract class AbstractJAXBProvid
protected List<String> inDropElements;
protected Map<String, String> inElementsMap;
protected Map<String, String> inAppendMap;
+ protected Map<Long, SoftReference<JAXBMarshallerUnmarshallerCache>>
threadMarshallerCaches
+ = new HashMap<Long, SoftReference<JAXBMarshallerUnmarshallerCache>>();
private boolean attributesToElements;
private MessageContext mc;
@@ -349,6 +351,7 @@ public abstract class AbstractJAXBProvid
}
}
+
public JAXBContext getPackageContext(Class<?> type) {
if (type == null || type == JAXBElement.class) {
return null;
@@ -372,6 +375,24 @@ public abstract class AbstractJAXBProvid
}
}
+ public JAXBMarshallerUnmarshallerCache getThreadMarshallerCache(Thread
thread) {
+ JAXBMarshallerUnmarshallerCache marshallerUnMarshallerCache = null;
+ synchronized (threadMarshallerCaches) {
+ SoftReference<JAXBMarshallerUnmarshallerCache>
marshallerUnMarshallerCacheRef =
+ threadMarshallerCaches.get(thread.getId());
+ if (marshallerUnMarshallerCacheRef != null) {
+ marshallerUnMarshallerCache =
marshallerUnMarshallerCacheRef.get();
+ }
+ if (marshallerUnMarshallerCache == null) {
+ marshallerUnMarshallerCache = new
JAXBMarshallerUnmarshallerCache();
+ threadMarshallerCaches
+ .put(thread.getId(),
+ new
SoftReference<JAXBMarshallerUnmarshallerCache>(marshallerUnMarshallerCache));
+ }
+ return marshallerUnMarshallerCache;
+ }
+ }
+
protected boolean isSupported(Class<?> type, Type genericType,
Annotation[] anns) {
if (jaxbElementClassMap != null &&
jaxbElementClassMap.containsKey(type.getName())
|| isSkipJaxbChecks()) {
@@ -408,7 +429,10 @@ public abstract class AbstractJAXBProvid
throws JAXBException {
JAXBContext context = isCollection ? getCollectionContext(cls)
: getJAXBContext(cls, genericType);
- Unmarshaller unmarshaller = context.createUnmarshaller();
+
+ JAXBMarshallerUnmarshallerCache marshallerUnmarshallerCache =
+ getThreadMarshallerCache(Thread.currentThread());
+ Unmarshaller unmarshaller =
marshallerUnmarshallerCache.getUnmarshall(context);
if (schema != null) {
unmarshaller.setSchema(schema);
}
@@ -427,9 +451,16 @@ public abstract class AbstractJAXBProvid
? ((JAXBElement)obj).getDeclaredType() : cls;
JAXBContext context = getJAXBContext(objClazz, genericType);
- Marshaller marshaller = context.createMarshaller();
+ JAXBMarshallerUnmarshallerCache marshallerUnmarshallerCache =
+ getThreadMarshallerCache(Thread.currentThread());
+ Marshaller marshaller =
marshallerUnmarshallerCache.getMarshall(context);
+ // need to set this value to make JAXRSClientServerBookTest passed
+ marshaller.setProperty(Marshaller.JAXB_FRAGMENT, Boolean.FALSE);
if (enc != null) {
marshaller.setProperty(Marshaller.JAXB_ENCODING, enc);
+ } else {
+ // set the default the value to the marshaller
+ marshaller.setProperty(Marshaller.JAXB_ENCODING, "UTF-8");
}
return marshaller;
}
@@ -675,6 +706,40 @@ public abstract class AbstractJAXBProvid
}
+ protected static class JAXBMarshallerUnmarshallerCache {
+ private Map<JAXBContext, Marshaller> marshallers = new
HashMap<JAXBContext, Marshaller>();
+ private Map<JAXBContext, Unmarshaller> unmarshallers = new
HashMap<JAXBContext, Unmarshaller>();
+
+ public Marshaller getMarshall(JAXBContext jaxbContext) throws
JAXBException {
+ if (jaxbContext == null) {
+ return null;
+ }
+ // don't need the synchronized statement, as this ojbect is used
per thread
+ Marshaller marshaller = marshallers.get(jaxbContext);
+ if (marshaller == null) {
+ marshaller = jaxbContext.createMarshaller();
+ marshallers.put(jaxbContext, marshaller);
+ }
+ return marshaller;
+
+ }
+
+ public Unmarshaller getUnmarshall(JAXBContext jaxbContext) throws
JAXBException {
+ if (jaxbContext == null) {
+ return null;
+ }
+ // don't need the synchronized statement, as this ojbect is used
per thread
+ Unmarshaller unmarshaller = unmarshallers.get(jaxbContext);
+ if (unmarshaller == null) {
+ unmarshaller = jaxbContext.createUnmarshaller();
+ unmarshallers.put(jaxbContext, unmarshaller);
+ }
+ return unmarshaller;
+
+ }
+
+ }
+
protected static class OutTransformWriter extends
DelegatingXMLStreamWriter {
private QNamesMap elementsMap;
private Map<QName, QName> appendMap = new HashMap<QName, QName>(5);
Modified:
cxf/branches/2.3.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/JAXBElementProvider.java
URL:
http://svn.apache.org/viewvc/cxf/branches/2.3.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/JAXBElementProvider.java?rev=1044309&r1=1044308&r2=1044309&view=diff
==============================================================================
---
cxf/branches/2.3.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/JAXBElementProvider.java
(original)
+++
cxf/branches/2.3.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/JAXBElementProvider.java
Fri Dec 10 11:46:00 2010
@@ -51,7 +51,6 @@ import javax.xml.stream.XMLOutputFactory
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import javax.xml.stream.XMLStreamWriter;
-import javax.xml.transform.stream.StreamSource;
import org.apache.cxf.helpers.CastUtils;
import org.apache.cxf.jaxb.NamespaceMapper;
@@ -162,7 +161,7 @@ public class JAXBElementProvider extends
if (JAXBElement.class.isAssignableFrom(type)
|| unmarshalAsJaxbElement
|| jaxbElementClassMap != null &&
jaxbElementClassMap.containsKey(theType.getName())) {
- response = unmarshaller.unmarshal(new StreamSource(is),
theType);
+ response =
unmarshaller.unmarshal(StaxUtils.createXMLStreamReader(is), theType);
} else {
response = doUnmarshal(unmarshaller, type, is, mt);
}
@@ -222,7 +221,8 @@ public class JAXBElementProvider extends
protected Object unmarshalFromInputStream(Unmarshaller unmarshaller,
InputStream is, MediaType mt)
throws JAXBException {
- return unmarshaller.unmarshal(is);
+ // Try to create the read before unmarshalling the stream
+ return unmarshaller.unmarshal(StaxUtils.createXMLStreamReader(is));
}
protected Object unmarshalFromReader(Unmarshaller unmarshaller,
XMLStreamReader reader, MediaType mt)