8025030: Enhance stream handling
Summary: Avoiding caching data initialized via TCCL in static context; fix also reviewed by Iaroslav Savytskyi, Alexander Fomin
Reviewed-by: ahgross, mgrebac, skoivu
--- a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/bind/DatatypeConverterImpl.java Sun Dec 15 23:35:45 2013 +0100
+++ b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/bind/DatatypeConverterImpl.java Fri Feb 21 17:30:18 2014 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -27,9 +27,14 @@
import java.math.BigDecimal;
import java.math.BigInteger;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
import java.util.Calendar;
+import java.util.Collections;
import java.util.GregorianCalendar;
+import java.util.Map;
import java.util.TimeZone;
+import java.util.WeakHashMap;
import javax.xml.bind.DatatypeConverter;
import javax.xml.bind.DatatypeConverterInterface;
@@ -356,7 +361,7 @@
public static GregorianCalendar _parseDateTime(CharSequence s) {
String val = WhiteSpaceProcessor.trim(s).toString();
- return datatypeFactory.newXMLGregorianCalendar(val).toGregorianCalendar();
+ return getDatatypeFactory().newXMLGregorianCalendar(val).toGregorianCalendar();
}
public static String _printDateTime(Calendar val) {
@@ -722,14 +727,30 @@
}
return false;
}
- private static final DatatypeFactory datatypeFactory;
+
+ private static final Map<ClassLoader, DatatypeFactory> DF_CACHE = Collections.synchronizedMap(new WeakHashMap<ClassLoader, DatatypeFactory>());
- static {
- try {
- datatypeFactory = DatatypeFactory.newInstance();
- } catch (DatatypeConfigurationException e) {
- throw new Error(e);
+ public static DatatypeFactory getDatatypeFactory() {
+ ClassLoader tccl = AccessController.doPrivileged(new PrivilegedAction<ClassLoader>() {
+ public ClassLoader run() {
+ return Thread.currentThread().getContextClassLoader();
+ }
+ });
+ DatatypeFactory df = DF_CACHE.get(tccl);
+ if (df == null) {
+ synchronized (DatatypeConverterImpl.class) {
+ df = DF_CACHE.get(tccl);
+ if (df == null) { // to prevent multiple initialization
+ try {
+ df = DatatypeFactory.newInstance();
+ } catch (DatatypeConfigurationException e) {
+ throw new Error(Messages.FAILED_TO_INITIALE_DATATYPE_FACTORY.format(),e);
+ }
+ DF_CACHE.put(tccl, df);
+ }
+ }
}
+ return df;
}
private static final class CalendarFormatter {
@@ -1045,7 +1066,7 @@
@Deprecated
public Calendar parseTime(String lexicalXSDTime) {
- return datatypeFactory.newXMLGregorianCalendar(lexicalXSDTime).toGregorianCalendar();
+ return getDatatypeFactory().newXMLGregorianCalendar(lexicalXSDTime).toGregorianCalendar();
}
@Deprecated
@@ -1055,7 +1076,7 @@
@Deprecated
public Calendar parseDate(String lexicalXSDDate) {
- return datatypeFactory.newXMLGregorianCalendar(lexicalXSDDate).toGregorianCalendar();
+ return getDatatypeFactory().newXMLGregorianCalendar(lexicalXSDDate).toGregorianCalendar();
}
@Deprecated
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/bind/Messages.java Fri Feb 21 17:30:18 2014 +0100
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.xml.internal.bind;
+
+import java.text.MessageFormat;
+import java.util.ResourceBundle;
+
+/**
+ * Message resources
+ */
+enum Messages {
+ FAILED_TO_INITIALE_DATATYPE_FACTORY, // 0 args
+ ;
+
+ private static final ResourceBundle rb = ResourceBundle.getBundle(Messages.class.getName());
+
+ @Override
+ public String toString() {
+ return format();
+ }
+
+ public String format( Object... args ) {
+ return MessageFormat.format( rb.getString(name()), args );
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/bind/Messages.properties Fri Feb 21 17:30:18 2014 +0100
@@ -0,0 +1,27 @@
+#
+# Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation. Oracle designates this
+# particular file as subject to the "Classpath" exception as provided
+# by Oracle in the LICENSE file that accompanied this code.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#
+
+FAILED_TO_INITIALE_DATATYPE_FACTORY = \
+ Failed to initialize JAXP 1.3 DatatypeFactory class.
--- a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/bind/v2/model/impl/Messages.java Sun Dec 15 23:35:45 2013 +0100
+++ b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/bind/v2/model/impl/Messages.java Fri Feb 21 17:30:18 2014 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -60,7 +60,6 @@
PROPERTY_ORDER_CONTAINS_UNUSED_ENTRY, // 2 args
INVALID_XML_ENUM_VALUE, // 2 arg
- FAILED_TO_INITIALE_DATATYPE_FACTORY, // 0 args
NO_IMAGE_WRITER, // 1 arg
ILLEGAL_MIME_TYPE, // 2 args
--- a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/bind/v2/model/impl/RuntimeBuiltinLeafInfoImpl.java Sun Dec 15 23:35:45 2013 +0100
+++ b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/bind/v2/model/impl/RuntimeBuiltinLeafInfoImpl.java Fri Feb 21 17:30:18 2014 +0100
@@ -63,9 +63,7 @@
import javax.imageio.stream.ImageOutputStream;
import javax.xml.bind.ValidationEvent;
import javax.xml.bind.helpers.ValidationEventImpl;
-import javax.xml.datatype.DatatypeConfigurationException;
import javax.xml.datatype.DatatypeConstants;
-import javax.xml.datatype.DatatypeFactory;
import javax.xml.datatype.Duration;
import javax.xml.datatype.XMLGregorianCalendar;
import javax.xml.namespace.QName;
@@ -574,7 +572,8 @@
public XMLGregorianCalendar parse(CharSequence lexical) throws SAXException {
try {
- return datatypeFactory.newXMLGregorianCalendar(lexical.toString().trim()); // (.trim() - issue 396)
+ return DatatypeConverterImpl.getDatatypeFactory()
+ .newXMLGregorianCalendar(lexical.toString().trim()); // (.trim() - issue 396)
} catch (Exception e) {
UnmarshallingContext.getInstance().handleError(e);
return null;
@@ -844,7 +843,7 @@
public Duration parse(CharSequence lexical) {
TODO.checkSpec("JSR222 Issue #42");
- return datatypeFactory.newDuration(lexical.toString());
+ return DatatypeConverterImpl.getDatatypeFactory().newDuration(lexical.toString());
}
});
primaryList.add(
@@ -885,21 +884,6 @@
}
}
-
- /**
- * Cached instance of {@link DatatypeFactory} to create
- * {@link XMLGregorianCalendar} and {@link Duration}.
- */
- private static final DatatypeFactory datatypeFactory = init();
-
- private static DatatypeFactory init() {
- try {
- return DatatypeFactory.newInstance();
- } catch (DatatypeConfigurationException e) {
- throw new Error(Messages.FAILED_TO_INITIALE_DATATYPE_FACTORY.format(),e);
- }
- }
-
private static void checkXmlGregorianCalendarFieldRef(QName type,
XMLGregorianCalendar cal)throws javax.xml.bind.MarshalException{
StringBuilder buf = new StringBuilder();
--- a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/bind/v2/runtime/Messages.java Sun Dec 15 23:35:45 2013 +0100
+++ b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/bind/v2/runtime/Messages.java Fri Feb 21 17:30:18 2014 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -58,6 +58,7 @@
FAILED_TO_GENERATE_SCHEMA, // 0 args
ERROR_PROCESSING_SCHEMA, // 0 args
ILLEGAL_CONTENT, // 2 args
+ FAILED_TO_INITIALE_DATATYPE_FACTORY, // 2 args
;
private static final ResourceBundle rb = ResourceBundle.getBundle(Messages.class.getName());
--- a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/bind/v2/runtime/output/XMLStreamWriterOutput.java Sun Dec 15 23:35:45 2013 +0100
+++ b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/bind/v2/runtime/output/XMLStreamWriterOutput.java Fri Feb 21 17:30:18 2014 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -153,7 +153,6 @@
}
}
-
/**
* Reference to FI's XMLStreamWriter class, if FI can be loaded.
*/
@@ -162,9 +161,8 @@
private static Class initFIStAXWriterClass() {
try {
- ClassLoader loader = getClassLoader();
- Class llfisw = Class.forName("com.sun.xml.internal.org.jvnet.fastinfoset.stax.LowLevelFastInfosetStreamWriter", true, loader);
- Class sds = loader.loadClass("com.sun.xml.internal.fastinfoset.stax.StAXDocumentSerializer");
+ Class<?> llfisw = Class.forName("com.sun.xml.internal.org.jvnet.fastinfoset.stax.LowLevelFastInfosetStreamWriter");
+ Class<?> sds = Class.forName("com.sun.xml.internal.fastinfoset.stax.StAXDocumentSerializer");
// Check if StAXDocumentSerializer implements LowLevelFastInfosetStreamWriter
if (llfisw.isAssignableFrom(sds))
return sds;
@@ -179,8 +177,7 @@
try {
if (FI_STAX_WRITER_CLASS == null)
return null;
- ClassLoader loader = getClassLoader();
- Class c = Class.forName("com.sun.xml.internal.bind.v2.runtime.output.FastInfosetStreamWriterOutput", true, loader);
+ Class c = Class.forName("com.sun.xml.internal.bind.v2.runtime.output.FastInfosetStreamWriterOutput");
return c.getConstructor(FI_STAX_WRITER_CLASS, JAXBContextImpl.class);
} catch (Throwable e) {
return null;
@@ -195,8 +192,7 @@
private static Class initStAXExWriterClass() {
try {
- ClassLoader loader = getClassLoader();
- return Class.forName("com.sun.xml.internal.org.jvnet.staxex.XMLStreamWriterEx",true,loader);
+ return Class.forName("com.sun.xml.internal.org.jvnet.staxex.XMLStreamWriterEx");
} catch (Throwable e) {
return null;
}
@@ -204,20 +200,11 @@
private static Constructor<? extends XmlOutput> initStAXExOutputClass() {
try {
- ClassLoader loader = getClassLoader();
- Class c = Class.forName("com.sun.xml.internal.bind.v2.runtime.output.StAXExStreamWriterOutput",true, loader);
+ Class c = Class.forName("com.sun.xml.internal.bind.v2.runtime.output.StAXExStreamWriterOutput");
return c.getConstructor(STAXEX_WRITER_CLASS);
} catch (Throwable e) {
return null;
}
}
- private static ClassLoader getClassLoader() {
- ClassLoader cl = SecureLoader.getClassClassLoader(UnmarshallerImpl.class);
- if (cl == null) {
- cl = SecureLoader.getContextClassLoader();
- }
- return cl;
- }
-
}
--- a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/bind/v2/runtime/reflect/Messages.properties Sun Dec 15 23:35:45 2013 +0100
+++ b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/bind/v2/runtime/reflect/Messages.properties Fri Feb 21 17:30:18 2014 +0100
@@ -1,5 +1,5 @@
#
-# Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -38,3 +38,6 @@
NO_GETTER = \
The property has a setter "{0}" but no getter. \
For marshaller, please define getters.
+
+INVALID_XML_ENUM_VALUE = \
+ "{0}" is not a valid value for {1}.
--- a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/bind/v2/runtime/unmarshaller/StAXStreamConnector.java Sun Dec 15 23:35:45 2013 +0100
+++ b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/bind/v2/runtime/unmarshaller/StAXStreamConnector.java Fri Feb 21 17:30:18 2014 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -336,9 +336,8 @@
private static Class initFIStAXReaderClass() {
try {
- ClassLoader cl = getClassLoader();
- Class fisr = cl.loadClass("com.sun.xml.internal.org.jvnet.fastinfoset.stax.FastInfosetStreamReader");
- Class sdp = cl.loadClass("com.sun.xml.internal.fastinfoset.stax.StAXDocumentParser");
+ Class<?> fisr = Class.forName("com.sun.xml.internal.org.jvnet.fastinfoset.stax.FastInfosetStreamReader");
+ Class<?> sdp = Class.forName("com.sun.xml.internal.fastinfoset.stax.StAXDocumentParser");
// Check if StAXDocumentParser implements FastInfosetStreamReader
if (fisr.isAssignableFrom(sdp))
return sdp;
@@ -354,7 +353,7 @@
if (FI_STAX_READER_CLASS == null)
return null;
- Class c = getClassLoader().loadClass(
+ Class c = Class.forName(
"com.sun.xml.internal.bind.v2.runtime.unmarshaller.FastInfosetConnector");
return c.getConstructor(FI_STAX_READER_CLASS,XmlVisitor.class);
} catch (Throwable e) {
@@ -370,7 +369,7 @@
private static Class initStAXExReader() {
try {
- return getClassLoader().loadClass("com.sun.xml.internal.org.jvnet.staxex.XMLStreamReaderEx");
+ return Class.forName("com.sun.xml.internal.org.jvnet.staxex.XMLStreamReaderEx");
} catch (Throwable e) {
return null;
}
@@ -378,19 +377,11 @@
private static Constructor<? extends StAXConnector> initStAXExConnector() {
try {
- Class c = getClassLoader().loadClass("com.sun.xml.internal.bind.v2.runtime.unmarshaller.StAXExConnector");
+ Class c = Class.forName("com.sun.xml.internal.bind.v2.runtime.unmarshaller.StAXExConnector");
return c.getConstructor(STAX_EX_READER_CLASS,XmlVisitor.class);
} catch (Throwable e) {
return null;
}
}
- private static ClassLoader getClassLoader() {
- ClassLoader cl = SecureLoader.getClassClassLoader(UnmarshallerImpl.class);
- if (cl == null) {
- cl = SecureLoader.getContextClassLoader();
- }
- return cl;
- }
-
}