--- old/src/java.xml.ws/share/classes/javax/xml/soap/FactoryFinder.java 2015-10-26 13:45:50.000000000 +0100 +++ new/src/java.xml.ws/share/classes/javax/xml/soap/FactoryFinder.java 2015-10-26 13:45:50.000000000 +0100 @@ -26,94 +26,46 @@ package javax.xml.soap; import java.io.*; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.security.AccessController; +import java.security.PrivilegedAction; import java.util.Properties; +import java.util.logging.Level; +import java.util.logging.Logger; class FactoryFinder { - /** - * Creates an instance of the specified class using the specified - * {@code ClassLoader} object. - * - * @exception SOAPException if the given class could not be found - * or could not be instantiated - */ - private static Object newInstance(String className, - ClassLoader classLoader) - throws SOAPException - { - try { - Class spiClass = safeLoadClass(className, classLoader); - return spiClass.newInstance(); + private static final Logger logger = Logger.getLogger("javax.xml.soap"); - } catch (ClassNotFoundException x) { - throw new SOAPException("Provider " + className + " not found", x); - } catch (Exception x) { - throw new SOAPException("Provider " + className + " could not be instantiated: " + x, x); - } - } - - /** - * Finds the implementation {@code Class} object for the given - * factory name, or null if that fails. - *

- * This method is package private so that this code can be shared. - * - * @return the {@code Class} object of the specified message factory; - * or {@code null} - * - * @param factoryId the name of the factory to find, which is - * a system property - * @exception SOAPException if there is a SOAP error - */ - static Object find(String factoryId) - throws SOAPException - { - return find(factoryId, null, false); - } - - /** - * Finds the implementation {@code Class} object for the given - * factory name, or if that fails, finds the {@code Class} object - * for the given fallback class name. The arguments supplied must be - * used in order. If using the first argument is successful, the second - * one will not be used. - *

- * This method is package private so that this code can be shared. - * - * @return the {@code Class} object of the specified message factory; - * may be {@code null} - * - * @param factoryId the name of the factory to find, which is - * a system property - * @param fallbackClassName the implementation class name, which is - * to be used only if nothing else - * is found; {@code null} to indicate that - * there is no fallback class name - * @exception SOAPException if there is a SOAP error - */ - static Object find(String factoryId, String fallbackClassName) - throws SOAPException - { - return find(factoryId, fallbackClassName, true); - } + private static final ServiceLoaderUtil.ExceptionHandler EXCEPTION_HANDLER = + new ServiceLoaderUtil.ExceptionHandler() { + @Override + public SOAPException createException(Throwable throwable, String message) { + return new SOAPException(message, throwable); + } + }; /** * Finds the implementation {@code Class} object for the given - * factory name, or if that fails, finds the {@code Class} object - * for the given default class name, but only if {@code tryFallback} - * is {@code true}. The arguments supplied must be used in order - * If using the first argument is successful, the second one will not - * be used. Note the default class name may be needed even if fallback - * is not to be attempted, so certain error conditions can be handled. + * factory type. If it fails and {@code tryFallback} is {@code true} + * finds the {@code Class} object for the given default class name. + * The arguments supplied must be used in order + * Note the default class name may be needed even if fallback + * is not to be attempted in order to check if requested type is fallback. *

* This method is package private so that this code can be shared. * * @return the {@code Class} object of the specified message factory; * may not be {@code null} * - * @param factoryId the name of the factory to find, which is - * a system property + * @param factoryClass factory abstract class or interface to be found + * @param deprecatedFactoryId deprecated name of a factory; it is used for types + * where class name is different from a name + * being searched (in previous spec). * @param defaultClassName the implementation class name, which is * to be used only if nothing else * is found; {@code null} to indicate @@ -122,63 +74,52 @@ * fallback * @exception SOAPException if there is a SOAP error */ - static Object find(String factoryId, String defaultClassName, - boolean tryFallback) throws SOAPException { - ClassLoader classLoader; - try { - classLoader = Thread.currentThread().getContextClassLoader(); - } catch (Exception x) { - throw new SOAPException(x.toString(), x); - } + @SuppressWarnings("unchecked") + static T find(Class factoryClass, + String defaultClassName, + boolean tryFallback, String deprecatedFactoryId) throws SOAPException { + + ClassLoader tccl = ServiceLoaderUtil.contextClassLoader(EXCEPTION_HANDLER); + String factoryId = factoryClass.getName(); // Use the system property first - try { - String systemProp = - System.getProperty( factoryId ); - if( systemProp!=null) { - return newInstance(systemProp, classLoader); + String className = fromSystemProperty(factoryId, deprecatedFactoryId); + if (className != null) { + Object result = newInstance(className, defaultClassName, tccl); + if (result != null) { + return (T) result; } - } catch (SecurityException se) { } // try to read from $java.home/lib/jaxm.properties - try { - String javah=System.getProperty( "java.home" ); - String configFile = javah + File.separator + - "lib" + File.separator + "jaxm.properties"; - File f=new File( configFile ); - if( f.exists()) { - Properties props=new Properties(); - props.load( new FileInputStream(f)); - String factoryClassName = props.getProperty(factoryId); - return newInstance(factoryClassName, classLoader); + className = fromJDKProperties(factoryId, deprecatedFactoryId); + if (className != null) { + Object result = newInstance(className, defaultClassName, tccl); + if (result != null) { + return (T) result; } - } catch(Exception ex ) { } - String serviceId = "META-INF/services/" + factoryId; - // try to find services in CLASSPATH - try { - InputStream is=null; - if (classLoader == null) { - is=ClassLoader.getSystemResourceAsStream(serviceId); - } else { - is=classLoader.getResourceAsStream(serviceId); - } - - if( is!=null ) { - BufferedReader rd = - new BufferedReader(new InputStreamReader(is, "UTF-8")); - - String factoryClassName = rd.readLine(); - rd.close(); + // standard services: java.util.ServiceLoader + T factory = ServiceLoaderUtil.firstByServiceLoader( + factoryClass, + logger, + EXCEPTION_HANDLER); + if (factory != null) { + return factory; + } - if (factoryClassName != null && - ! "".equals(factoryClassName)) { - return newInstance(factoryClassName, classLoader); - } + // try to find services in CLASSPATH + className = fromMetaInfServices(deprecatedFactoryId, tccl); + if (className != null) { + logger.log(Level.WARNING, + "Using deprecated META-INF/services mechanism with non-standard property: {0}. " + + "Property {1} should be used instead.", + new Object[]{deprecatedFactoryId, factoryId}); + Object result = newInstance(className, defaultClassName, tccl); + if (result != null) { + return (T) result; } - } catch( Exception ex ) { } // If not found and fallback should not be tried, return a null result. @@ -191,46 +132,133 @@ throw new SOAPException( "Provider for " + factoryId + " cannot be found", null); } - return newInstance(defaultClassName, classLoader); + return (T) newInstance(defaultClassName, defaultClassName, tccl); } - /** - * Loads the class, provided that the calling thread has an access to the - * class being loaded. If this is the specified default factory class and it - * is restricted by package.access we get a SecurityException and can do a - * Class.forName() on it so it will be loaded by the bootstrap class loader. - */ - private static Class safeLoadClass(String className, - ClassLoader classLoader) - throws ClassNotFoundException { - try { - // make sure that the current thread has an access to the package of the given name. - SecurityManager s = System.getSecurityManager(); - if (s != null) { - int i = className.lastIndexOf('.'); - if (i != -1) { - s.checkPackageAccess(className.substring(0, i)); + // in most cases there is no deprecated factory id + static T find(Class factoryClass, + String defaultClassName, + boolean tryFallback) throws SOAPException { + return find(factoryClass, defaultClassName, tryFallback, null); + } + + private static Object newInstance(String className, String defaultClassName, ClassLoader tccl) throws SOAPException { + return ServiceLoaderUtil.newInstance( + className, + defaultClassName, + tccl, + EXCEPTION_HANDLER); + } + + // used only for deprecatedFactoryId; + // proper factoryId searched by java.util.ServiceLoader + private static String fromMetaInfServices(String deprecatedFactoryId, ClassLoader tccl) { + String serviceId = "META-INF/services/" + deprecatedFactoryId; + logger.log(Level.FINE, "Checking deprecated {0} resource", serviceId); + + try (InputStream is = + tccl == null ? + ClassLoader.getSystemResourceAsStream(serviceId) + : + tccl.getResourceAsStream(serviceId)) { + + if (is != null) { + String factoryClassName; + try (InputStreamReader isr = new InputStreamReader(is, StandardCharsets.UTF_8); + BufferedReader rd = new BufferedReader(isr)) { + factoryClassName = rd.readLine(); + } + + logFound(factoryClassName); + if (factoryClassName != null && !"".equals(factoryClassName)) { + return factoryClassName; } } - if (classLoader == null) - return Class.forName(className); - else - return classLoader.loadClass(className); - } catch (SecurityException se) { - // (only) default implementation can be loaded - // using bootstrap class loader: - if (isDefaultImplementation(className)) - return Class.forName(className); - - throw se; + } catch (IOException e) { + // keep original behavior } + return null; } - private static boolean isDefaultImplementation(String className) { - return MessageFactory.DEFAULT_MESSAGE_FACTORY.equals(className) || - SOAPFactory.DEFAULT_SOAP_FACTORY.equals(className) || - SOAPConnectionFactory.DEFAULT_SOAP_CONNECTION_FACTORY.equals(className) || - SAAJMetaFactory.DEFAULT_META_FACTORY_CLASS.equals(className); + private static String fromJDKProperties(String factoryId, String deprecatedFactoryId) { + Path path = null; + try { + String JAVA_HOME = System.getProperty("java.home"); + path = Paths.get(JAVA_HOME, "conf", "jaxm.properties"); + logger.log(Level.FINE, "Checking configuration in {0}", path); + + // to ensure backwards compatibility + if (!Files.exists(path)) { + path = Paths.get(JAVA_HOME, "lib", "jaxm.properties"); + } + + logger.log(Level.FINE, "Checking configuration in {0}", path); + if (Files.exists(path)) { + Properties props = new Properties(); + try (InputStream inputStream = Files.newInputStream(path)) { + props.load(inputStream); + } + + // standard property + logger.log(Level.FINE, "Checking property {0}", factoryId); + String factoryClassName = props.getProperty(factoryId); + logFound(factoryClassName); + if (factoryClassName != null) { + return factoryClassName; + } + + // deprecated property + if (deprecatedFactoryId != null) { + logger.log(Level.FINE, "Checking deprecated property {0}", deprecatedFactoryId); + factoryClassName = props.getProperty(deprecatedFactoryId); + logFound(factoryClassName); + if (factoryClassName != null) { + logger.log(Level.WARNING, + "Using non-standard property: {0}. Property {1} should be used instead.", + new Object[]{deprecatedFactoryId, factoryId}); + return factoryClassName; + } + } + } + } catch (Exception ignored) { + logger.log(Level.SEVERE, "Error reading SAAJ configuration from [" + path + + "] file. Check it is accessible and has correct format.", ignored); + } + return null; + } + + private static String fromSystemProperty(String factoryId, String deprecatedFactoryId) { + String systemProp = getSystemProperty(factoryId); + if (systemProp != null) { + return systemProp; + } + if (deprecatedFactoryId != null) { + systemProp = getSystemProperty(deprecatedFactoryId); + if (systemProp != null) { + logger.log(Level.WARNING, + "Using non-standard property: {0}. Property {1} should be used instead.", + new Object[] {deprecatedFactoryId, factoryId}); + return systemProp; + } + } + return null; } + + private static String getSystemProperty(String property) { + logger.log(Level.FINE, "Checking system property {0}", property); + String value = AccessController.doPrivileged( + (PrivilegedAction) () -> System.getProperty(property)); + logFound(value); + return value; + } + + private static void logFound(String value) { + if (value != null) { + logger.log(Level.FINE, " found {0}", value); + } else { + logger.log(Level.FINE, " not found"); + } + } + } --- old/src/java.xml.ws/share/classes/javax/xml/soap/MessageFactory.java 2015-10-26 13:45:51.000000000 +0100 +++ new/src/java.xml.ws/share/classes/javax/xml/soap/MessageFactory.java 2015-10-26 13:45:51.000000000 +0100 @@ -68,27 +68,15 @@ */ public abstract class MessageFactory { - static final String DEFAULT_MESSAGE_FACTORY + private static final String DEFAULT_MESSAGE_FACTORY = "com.sun.xml.internal.messaging.saaj.soap.ver1_1.SOAPMessageFactory1_1Impl"; - static private final String MESSAGE_FACTORY_PROPERTY - = "javax.xml.soap.MessageFactory"; - /** * Creates a new {@code MessageFactory} object that is an instance - * of the default implementation (SOAP 1.1), + * of the default implementation (SOAP 1.1). * - * This method uses the following ordered lookup procedure to determine the MessageFactory implementation class to load: - *

- + * This method uses the lookup procedure specified in {@link javax.xml.soap} to locate and load the + * {@link javax.xml.soap.MessageFactory} class. * * @return a new instance of a {@code MessageFactory} * @@ -103,7 +91,7 @@ try { MessageFactory factory = (MessageFactory) FactoryFinder.find( - MESSAGE_FACTORY_PROPERTY, + MessageFactory.class, DEFAULT_MESSAGE_FACTORY, false); --- old/src/java.xml.ws/share/classes/javax/xml/soap/SAAJMetaFactory.java 2015-10-26 13:45:52.000000000 +0100 +++ new/src/java.xml.ws/share/classes/javax/xml/soap/SAAJMetaFactory.java 2015-10-26 13:45:52.000000000 +0100 @@ -27,25 +27,49 @@ /** * The access point for the implementation classes of the factories defined in the -* SAAJ API. All of the {@code newInstance} methods defined on factories in -* SAAJ 1.3 defer to instances of this class to do the actual object creation. +* SAAJ API. The {@code newInstance} methods defined on factories {@link SOAPFactory} and +* {@link MessageFactory} in SAAJ 1.3 defer to instances of this class to do the actual object creation. * The implementations of {@code newInstance()} methods (in SOAPFactory and MessageFactory) * that existed in SAAJ 1.2 have been updated to also delegate to the SAAJMetaFactory when the SAAJ 1.2 * defined lookup fails to locate the Factory implementation class name. * *

-* SAAJMetaFactory is a service provider interface. There are no public methods on this +* SAAJMetaFactory is a service provider interface and it uses similar lookup mechanism as other SAAJ factories +* to get actual instance: +* +*

+* +*

+* There are no public methods on this * class. * * @author SAAJ RI Development Team * @since 1.6, SAAJ 1.3 */ - public abstract class SAAJMetaFactory { - static private final String META_FACTORY_CLASS_PROPERTY = - "javax.xml.soap.MetaFactory"; - static final String DEFAULT_META_FACTORY_CLASS = - "com.sun.xml.internal.messaging.saaj.soap.SAAJMetaFactoryImpl"; + + private static final String META_FACTORY_DEPRECATED_CLASS_PROPERTY = + "javax.xml.soap.MetaFactory"; + + private static final String DEFAULT_META_FACTORY_CLASS = + "com.sun.xml.internal.messaging.saaj.soap.SAAJMetaFactoryImpl"; /** * Creates a new instance of a concrete {@code SAAJMetaFactory} object. @@ -54,27 +78,20 @@ * implementation. Service providers provide the name of their {@code SAAJMetaFactory} * implementation. * - * This method uses the following ordered lookup procedure to determine the SAAJMetaFactory implementation class to load: - *

+ * This method uses the lookup procedure specified in {@link javax.xml.soap} to locate and load the + * {@link javax.xml.soap.SAAJMetaFactory} class. * * @return a concrete {@code SAAJMetaFactory} object * @exception SOAPException if there is an error in creating the {@code SAAJMetaFactory} */ static SAAJMetaFactory getInstance() throws SOAPException { try { - SAAJMetaFactory instance = - (SAAJMetaFactory) FactoryFinder.find( - META_FACTORY_CLASS_PROPERTY, - DEFAULT_META_FACTORY_CLASS); - return instance; + return FactoryFinder.find( + SAAJMetaFactory.class, + DEFAULT_META_FACTORY_CLASS, + true, + META_FACTORY_DEPRECATED_CLASS_PROPERTY); + } catch (Exception e) { throw new SOAPException( "Unable to create SAAJ meta-factory" + e.getMessage()); @@ -88,6 +105,7 @@ * the given {@code String} protocol. * * @param protocol a {@code String} indicating the protocol + * @return a {@link MessageFactory}, not null * @exception SOAPException if there is an error in creating the * MessageFactory * @see SOAPConstants#SOAP_1_1_PROTOCOL @@ -102,6 +120,7 @@ * the given {@code String} protocol. * * @param protocol a {@code String} indicating the protocol + * @return a {@link SOAPFactory}, not null * @exception SOAPException if there is an error in creating the * SOAPFactory * @see SOAPConstants#SOAP_1_1_PROTOCOL --- old/src/java.xml.ws/share/classes/javax/xml/soap/SOAPConnectionFactory.java 2015-10-26 13:45:53.000000000 +0100 +++ new/src/java.xml.ws/share/classes/javax/xml/soap/SOAPConnectionFactory.java 2015-10-26 13:45:52.000000000 +0100 @@ -36,23 +36,21 @@ * @since 1.6 */ public abstract class SOAPConnectionFactory { + /** * A constant representing the default value for a {@code SOAPConnection} * object. The default is the point-to-point SOAP connection. */ - static final String DEFAULT_SOAP_CONNECTION_FACTORY - = "com.sun.xml.internal.messaging.saaj.client.p2p.HttpSOAPConnectionFactory"; - - /** - * A constant representing the {@code SOAPConnection} class. - */ - static private final String SF_PROPERTY - = "javax.xml.soap.SOAPConnectionFactory"; + private static final String DEFAULT_SOAP_CONNECTION_FACTORY + = "com.sun.xml.internal.messaging.saaj.client.p2p.HttpSOAPConnectionFactory"; /** * Creates an instance of the default * {@code SOAPConnectionFactory} object. * + * This method uses the lookup procedure specified in {@link javax.xml.soap} to locate and load the + * {@link javax.xml.soap.SOAPConnectionFactory} class. + * * @return a new instance of a default * {@code SOAPConnectionFactory} object * @@ -66,9 +64,10 @@ throws SOAPException, UnsupportedOperationException { try { - return (SOAPConnectionFactory) - FactoryFinder.find(SF_PROPERTY, - DEFAULT_SOAP_CONNECTION_FACTORY); + return FactoryFinder.find( + SOAPConnectionFactory.class, + DEFAULT_SOAP_CONNECTION_FACTORY, + true); } catch (Exception ex) { throw new SOAPException("Unable to create SOAP connection factory: " +ex.getMessage()); --- old/src/java.xml.ws/share/classes/javax/xml/soap/SOAPFactory.java 2015-10-26 13:45:53.000000000 +0100 +++ new/src/java.xml.ws/share/classes/javax/xml/soap/SOAPFactory.java 2015-10-26 13:45:53.000000000 +0100 @@ -48,17 +48,10 @@ public abstract class SOAPFactory { /** - * A constant representing the property used to lookup the name of - * a {@code SOAPFactory} implementation class. - */ - static private final String SOAP_FACTORY_PROPERTY = - "javax.xml.soap.SOAPFactory"; - - /** * Class name of default {@code SOAPFactory} implementation. */ - static final String DEFAULT_SOAP_FACTORY - = "com.sun.xml.internal.messaging.saaj.soap.ver1_1.SOAPFactory1_1Impl"; + private static final String DEFAULT_SOAP_FACTORY + = "com.sun.xml.internal.messaging.saaj.soap.ver1_1.SOAPFactory1_1Impl"; /** * Creates a {@code SOAPElement} object from an existing DOM @@ -239,18 +232,10 @@ /** * Creates a new {@code SOAPFactory} object that is an instance of - * the default implementation (SOAP 1.1), + * the default implementation (SOAP 1.1). * - * This method uses the following ordered lookup procedure to determine the SOAPFactory implementation class to load: - * + * This method uses the lookup procedure specified in {@link javax.xml.soap} to locate and load the + * {@link javax.xml.soap.SOAPFactory} class. * * @return a new instance of a {@code SOAPFactory} * @@ -262,10 +247,13 @@ throws SOAPException { try { - SOAPFactory factory = (SOAPFactory) FactoryFinder.find( - SOAP_FACTORY_PROPERTY, DEFAULT_SOAP_FACTORY, false); - if (factory != null) - return factory; + SOAPFactory factory = FactoryFinder.find( + SOAPFactory.class, + DEFAULT_SOAP_FACTORY, + false); + if (factory != null) return factory; + + // leave it on SAAJMetaFactory return newInstance(SOAPConstants.SOAP_1_1_PROTOCOL); } catch (Exception ex) { throw new SOAPException( --- /dev/null 2015-10-26 13:45:54.000000000 +0100 +++ new/src/java.xml.ws/share/classes/javax/xml/soap/ServiceLoaderUtil.java 2015-10-26 13:45:54.000000000 +0100 @@ -0,0 +1,125 @@ +/* + * Copyright (c) 2015, 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 javax.xml.soap; + +import java.util.ServiceLoader; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * Shared ServiceLoader/FactoryFinder Utils shared among SAAJ, JAXB and JAXWS + * Class duplicated to all those projects. + * + * @author Miroslav.Kos@oracle.com + */ +class ServiceLoaderUtil { + + static P firstByServiceLoader(Class

spiClass, + Logger logger, + ExceptionHandler handler) throws T { + logger.log(Level.FINE, "Using java.util.ServiceLoader to find {0}", spiClass.getName()); + // service discovery + try { + ServiceLoader

serviceLoader = ServiceLoader.load(spiClass); + + for (P impl : serviceLoader) { + logger.fine("ServiceProvider loading Facility used; returning object [" + + impl.getClass().getName() + "]"); + + return impl; + } + } catch (Throwable t) { + throw handler.createException(t, "Error while searching for service [" + spiClass.getName() + "]"); + } + return null; + } + + static void checkPackageAccess(String className) { + // make sure that the current thread has an access to the package of the given name. + SecurityManager s = System.getSecurityManager(); + if (s != null) { + int i = className.lastIndexOf('.'); + if (i != -1) { + s.checkPackageAccess(className.substring(0, i)); + } + } + } + + static Class nullSafeLoadClass(String className, ClassLoader classLoader) throws ClassNotFoundException { + if (classLoader == null) { + return Class.forName(className); + } else { + return classLoader.loadClass(className); + } + } + + // Returns instance of required class. It checks package access (security) + // unless it is defaultClassname. It means if you are trying to instantiate + // default implementation (fallback), pass the class name to both first and second parameter. + static Object newInstance(String className, + String defaultImplClassName, ClassLoader classLoader, + final ExceptionHandler handler) throws T { + try { + return safeLoadClass(className, defaultImplClassName, classLoader).newInstance(); + } catch (ClassNotFoundException x) { + throw handler.createException(x, "Provider " + className + " not found"); + } catch (Exception x) { + throw handler.createException(x, "Provider " + className + " could not be instantiated: " + x); + } + } + + static Class safeLoadClass(String className, + String defaultImplClassName, + ClassLoader classLoader) throws ClassNotFoundException { + + try { + checkPackageAccess(className); + } catch (SecurityException se) { + // anyone can access the platform default factory class without permission + if (defaultImplClassName != null && defaultImplClassName.equals(className)) { + return Class.forName(className); + } + // not platform default implementation ... + throw se; + } + return nullSafeLoadClass(className, classLoader); + } + + static ClassLoader contextClassLoader(ExceptionHandler exceptionHandler) throws T { + try { + return Thread.currentThread().getContextClassLoader(); + } catch (Exception x) { + throw exceptionHandler.createException(x, x.toString()); + } + } + + static abstract class ExceptionHandler { + + public abstract T createException(Throwable throwable, String message); + + } + +} --- /dev/null 2015-10-26 13:45:55.000000000 +0100 +++ new/src/java.xml.ws/share/classes/javax/xml/soap/package-info.java 2015-10-26 13:45:54.000000000 +0100 @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2005, 2015, 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. + */ + +/** + * Provides the API for creating and building SOAP messages. This package + * is defined in the SOAP with Attachments API for JavaTM + * (SAAJ) 1.4 specification. + * + *

The API in the javax.xml.soap package allows you to do the following: + * + *

+ * + *

+ * In addition the APIs in the javax.xml.soap package extend + * their counterparts in the org.w3c.dom package. This means that + * the SOAPPart of a SOAPMessage is also a DOM Level + * 2 Document, and can be manipulated as such by applications, + * tools and libraries that use DOM (see http://www.w3.org/DOM/ for more information). + * It is important to note that, while it is possible to use DOM APIs to add + * ordinary DOM nodes to a SAAJ tree, the SAAJ APIs are still required to return + * SAAJ types when examining or manipulating the tree. In order to accomplish + * this the SAAJ APIs (specifically {@link javax.xml.soap.SOAPElement#getChildElements()}) + * are allowed to silently replace objects that are incorrectly typed relative + * to SAAJ requirements with equivalent objects of the required type. These + * replacements must never cause the logical structure of the tree to change, + * so from the perspective of the DOM APIs the tree will remain unchanged. However, + * the physical composition of the tree will have changed so that references + * to the nodes that were replaced will refer to nodes that are no longer a + * part of the tree. The SAAJ APIs are not allowed to make these replacements + * if they are not required so the replacement objects will never subsequently + * be silently replaced by future calls to the SAAJ API. + *

+ * What this means in practical terms is that an application that starts to use + * SAAJ APIs on a tree after manipulating it using DOM APIs must assume that the + * tree has been translated into an all SAAJ tree and that any references to objects + * within the tree that were obtained using DOM APIs are no longer valid. Switching + * from SAAJ APIs to DOM APIs is not allowed to cause invalid references and + * neither is using SAAJ APIs exclusively. It is only switching from using DOM + * APIs on a particular SAAJ tree to using SAAJ APIs that causes the risk of + * invalid references. + * + *

Discovery of SAAJ implementation

+ *

+ * There are several factories defined in the SAAJ API to discover and load specific implementation: + * + *

+ * + * First three define {@code newInstance()} method which uses a common lookup procedure to determine + * the implementation class: + * + * + */ +package javax.xml.soap; --- old/src/java.xml.ws/share/classes/javax/xml/soap/package.html 2015-10-26 13:45:55.000000000 +0100 +++ /dev/null 2015-10-26 13:45:55.000000000 +0100 @@ -1,92 +0,0 @@ - - - - - - - - - - - Provides the API for creating and building SOAP messages. This package - is defined in the SOAP with Attachments API for JavaTM (SAAJ) 1.3 specification. -

The API in the javax.xml.soap package allows you to do the - following:

- - - -

- - - - - - -

-In addition the APIs in the javax.xml.soap package extend -their counterparts in the org.w3c.dom package. This means that -the SOAPPart of a SOAPMessage is also a DOM Level -2 Document, and can be manipulated as such by applications, -tools and libraries that use DOM (see http://www.w3.org/DOM/ for more information). -It is important to note that, while it is possible to use DOM APIs to add -ordinary DOM nodes to a SAAJ tree, the SAAJ APIs are still required to return -SAAJ types when examining or manipulating the tree. In order to accomplish -this the SAAJ APIs (specifically {@link javax.xml.soap.SOAPElement#getChildElements()}) -are allowed to silently replace objects that are incorrectly typed relative -to SAAJ requirements with equivalent objects of the required type. These -replacements must never cause the logical structure of the tree to change, -so from the perspective of the DOM APIs the tree will remain unchanged. However, -the physical composition of the tree will have changed so that references -to the nodes that were replaced will refer to nodes that are no longer a -part of the tree. The SAAJ APIs are not allowed to make these replacements -if they are not required so the replacement objects will never subsequently -be silently replaced by future calls to the SAAJ API. -

-What this means in -practical terms is that an application that starts to use SAAJ APIs on a -tree after manipulating it using DOM APIs must assume that the tree has been -translated into an all SAAJ tree and that any references to objects within -the tree that were obtained using DOM APIs are no longer valid. Switching -from SAAJ APIs to DOM APIs is not allowed to cause invalid references and -neither is using SAAJ APIs exclusively. It is only switching from using DOM -APIs on a particular SAAJ tree to using SAAJ APIs that causes the risk of -invalid references.
- - -