# HG changeset patch # User mkos # Date 1392312010 -3600 # Node ID cfc3c8286c3be92e139760dc4e6bebf9d32b8043 # Parent cc0582e79419b3dbcaee7dc92f0f1b25206e1704 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 diff -r cc0582e79419 -r cfc3c8286c3b src/share/jaxws_classes/com/sun/xml/internal/bind/DatatypeConverterImpl.java --- a/src/share/jaxws_classes/com/sun/xml/internal/bind/DatatypeConverterImpl.java Tue Feb 11 13:11:31 2014 -0800 +++ b/src/share/jaxws_classes/com/sun/xml/internal/bind/DatatypeConverterImpl.java Thu Feb 13 18:20:10 2014 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2011, 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; @@ -352,7 +357,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) { @@ -718,14 +723,30 @@ } return false; } - private static final DatatypeFactory datatypeFactory; + + private static final Map DF_CACHE = Collections.synchronizedMap(new WeakHashMap()); - static { - try { - datatypeFactory = DatatypeFactory.newInstance(); - } catch (DatatypeConfigurationException e) { - throw new Error(e); + public static DatatypeFactory getDatatypeFactory() { + ClassLoader tccl = AccessController.doPrivileged(new PrivilegedAction() { + 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 { diff -r cc0582e79419 -r cfc3c8286c3b src/share/jaxws_classes/com/sun/xml/internal/bind/Messages.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/jaxws_classes/com/sun/xml/internal/bind/Messages.java Thu Feb 13 18:20:10 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 ); + } +} diff -r cc0582e79419 -r cfc3c8286c3b src/share/jaxws_classes/com/sun/xml/internal/bind/Messages.properties --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/jaxws_classes/com/sun/xml/internal/bind/Messages.properties Thu Feb 13 18:20:10 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. diff -r cc0582e79419 -r cfc3c8286c3b src/share/jaxws_classes/com/sun/xml/internal/bind/v2/model/impl/Messages.java --- a/src/share/jaxws_classes/com/sun/xml/internal/bind/v2/model/impl/Messages.java Tue Feb 11 13:11:31 2014 -0800 +++ b/src/share/jaxws_classes/com/sun/xml/internal/bind/v2/model/impl/Messages.java Thu Feb 13 18:20:10 2014 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2011, 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 diff -r cc0582e79419 -r cfc3c8286c3b src/share/jaxws_classes/com/sun/xml/internal/bind/v2/model/impl/Messages.properties --- a/src/share/jaxws_classes/com/sun/xml/internal/bind/v2/model/impl/Messages.properties Tue Feb 11 13:11:31 2014 -0800 +++ b/src/share/jaxws_classes/com/sun/xml/internal/bind/v2/model/impl/Messages.properties Thu Feb 13 18:20:10 2014 +0100 @@ -1,5 +1,5 @@ # -# Copyright (c) 1997, 2011, 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 @@ -86,9 +86,6 @@ INVALID_XML_ENUM_VALUE = \ "{0}" is not a valid value for {1}. -FAILED_TO_INITIALE_DATATYPE_FACTORY = \ - Failed to initialize JAXP 1.3 DatatypeFactory class. - NO_IMAGE_WRITER = \ No javax.imageio.ImageWriter is available for the specified MIME type "{0}" diff -r cc0582e79419 -r cfc3c8286c3b src/share/jaxws_classes/com/sun/xml/internal/bind/v2/model/impl/RuntimeBuiltinLeafInfoImpl.java --- a/src/share/jaxws_classes/com/sun/xml/internal/bind/v2/model/impl/RuntimeBuiltinLeafInfoImpl.java Tue Feb 11 13:11:31 2014 -0800 +++ b/src/share/jaxws_classes/com/sun/xml/internal/bind/v2/model/impl/RuntimeBuiltinLeafInfoImpl.java Thu Feb 13 18:20:10 2014 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2011, 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,9 +60,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; @@ -565,7 +563,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; @@ -835,7 +834,7 @@ public Duration parse(CharSequence lexical) { TODO.checkSpec("JSR222 Issue #42"); - return datatypeFactory.newDuration(lexical.toString()); + return DatatypeConverterImpl.getDatatypeFactory().newDuration(lexical.toString()); } }); primaryList.add( @@ -876,21 +875,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(); diff -r cc0582e79419 -r cfc3c8286c3b src/share/jaxws_classes/com/sun/xml/internal/bind/v2/runtime/output/XMLStreamWriterOutput.java --- a/src/share/jaxws_classes/com/sun/xml/internal/bind/v2/runtime/output/XMLStreamWriterOutput.java Tue Feb 11 13:11:31 2014 -0800 +++ b/src/share/jaxws_classes/com/sun/xml/internal/bind/v2/runtime/output/XMLStreamWriterOutput.java Thu Feb 13 18:20:10 2014 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2011, 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 @@ -33,7 +33,6 @@ import com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl; import com.sun.xml.internal.bind.v2.runtime.XMLSerializer; -import com.sun.xml.internal.bind.v2.util.ClassLoaderRetriever; import org.xml.sax.SAXException; @@ -153,7 +152,6 @@ } } - /** * Reference to FI's XMLStreamWriter class, if FI can be loaded. */ @@ -162,9 +160,8 @@ private static Class initFIStAXWriterClass() { try { - ClassLoader loader = ClassLoaderRetriever.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 +176,7 @@ try { if (FI_STAX_WRITER_CLASS == null) return null; - ClassLoader loader = ClassLoaderRetriever.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 +191,7 @@ private static Class initStAXExWriterClass() { try { - ClassLoader loader = ClassLoaderRetriever.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,8 +199,7 @@ private static Constructor initStAXExOutputClass() { try { - ClassLoader loader = ClassLoaderRetriever.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; diff -r cc0582e79419 -r cfc3c8286c3b src/share/jaxws_classes/com/sun/xml/internal/bind/v2/runtime/unmarshaller/StAXStreamConnector.java --- a/src/share/jaxws_classes/com/sun/xml/internal/bind/v2/runtime/unmarshaller/StAXStreamConnector.java Tue Feb 11 13:11:31 2014 -0800 +++ b/src/share/jaxws_classes/com/sun/xml/internal/bind/v2/runtime/unmarshaller/StAXStreamConnector.java Thu Feb 13 18:20:10 2014 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2011, 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 @@ -33,7 +33,6 @@ import javax.xml.stream.XMLStreamReader; import com.sun.xml.internal.bind.WhiteSpaceProcessor; -import com.sun.xml.internal.bind.v2.util.ClassLoaderRetriever; import org.xml.sax.Attributes; import org.xml.sax.SAXException; @@ -337,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; @@ -355,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) { @@ -371,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; } @@ -379,15 +377,10 @@ private static Constructor 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; } } - - public static ClassLoader getClassLoader() { - return ClassLoaderRetriever.getClassLoader(); - } - } diff -r cc0582e79419 -r cfc3c8286c3b src/share/jaxws_classes/javax/xml/bind/DatatypeConverterImpl.java --- a/src/share/jaxws_classes/javax/xml/bind/DatatypeConverterImpl.java Tue Feb 11 13:11:31 2014 -0800 +++ b/src/share/jaxws_classes/javax/xml/bind/DatatypeConverterImpl.java Thu Feb 13 18:20:10 2014 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 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.namespace.QName; import javax.xml.namespace.NamespaceContext; @@ -418,7 +423,7 @@ public static GregorianCalendar _parseDateTime(CharSequence s) { String val = WhiteSpaceProcessor.trim(s).toString(); - return datatypeFactory.newXMLGregorianCalendar(val).toGregorianCalendar(); + return getDatatypeFactory().newXMLGregorianCalendar(val).toGregorianCalendar(); } public String printDateTime(Calendar val) { @@ -492,7 +497,7 @@ } public Calendar parseTime(String lexicalXSDTime) { - return datatypeFactory.newXMLGregorianCalendar(lexicalXSDTime).toGregorianCalendar(); + return getDatatypeFactory().newXMLGregorianCalendar(lexicalXSDTime).toGregorianCalendar(); } public String printTime(Calendar val) { @@ -500,7 +505,7 @@ } public Calendar parseDate(String lexicalXSDDate) { - return datatypeFactory.newXMLGregorianCalendar(lexicalXSDDate).toGregorianCalendar(); + return getDatatypeFactory().newXMLGregorianCalendar(lexicalXSDDate).toGregorianCalendar(); } public String printDate(Calendar val) { @@ -882,14 +887,30 @@ } return false; } - private static final DatatypeFactory datatypeFactory; + + private static final Map DF_CACHE = Collections.synchronizedMap(new WeakHashMap()); - static { - try { - datatypeFactory = DatatypeFactory.newInstance(); - } catch (DatatypeConfigurationException e) { - throw new Error(e); + public static DatatypeFactory getDatatypeFactory() { + ClassLoader tccl = AccessController.doPrivileged(new PrivilegedAction() { + 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.format(Messages.FAILED_TO_INITIALE_DATATYPE_FACTORY), e); + } + DF_CACHE.put(tccl, df); + } + } } + return df; } private static final class CalendarFormatter { diff -r cc0582e79419 -r cfc3c8286c3b src/share/jaxws_classes/javax/xml/bind/Messages.java --- a/src/share/jaxws_classes/javax/xml/bind/Messages.java Tue Feb 11 13:11:31 2014 -0800 +++ b/src/share/jaxws_classes/javax/xml/bind/Messages.java Thu Feb 13 18:20:10 2014 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 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 @@ -88,4 +88,6 @@ static final String ILLEGAL_CAST = // 2 args "JAXBContext.IllegalCast"; + + static final String FAILED_TO_INITIALE_DATATYPE_FACTORY = "FAILED_TO_INITIALE_DATATYPE_FACTORY"; } diff -r cc0582e79419 -r cfc3c8286c3b src/share/jaxws_classes/javax/xml/bind/Messages.properties --- a/src/share/jaxws_classes/javax/xml/bind/Messages.properties Tue Feb 11 13:11:31 2014 -0800 +++ b/src/share/jaxws_classes/javax/xml/bind/Messages.properties Thu Feb 13 18:20:10 2014 +0100 @@ -1,5 +1,5 @@ # -# Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2003, 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 @@ -49,3 +49,6 @@ JAXBContext.IllegalCast = \ ClassCastException: attempting to cast {0} to {1}. Please make sure that you are specifying the proper ClassLoader. + +FAILED_TO_INITIALE_DATATYPE_FACTORY = \ + Failed to initialize JAXP 1.3 DatatypeFactory class.