< prev index next >
src/java.xml.bind/share/classes/javax/xml/bind/JAXBContext.java
Print this page
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2016, 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
@@ -92,11 +92,11 @@
* the schema to be unmarshalled as the root of an instance document.
* The {@code JAXBContext} object
* allows the merging of global elements and type definitions across a set of schemas (listed
* in the {@code contextPath}). Since each schema in the schema set can belong
* to distinct namespaces, the unification of schemas to an unmarshalling
- * context should be namespace independent. This means that a client
+ * context must be namespace independent. This means that a client
* application is able to unmarshal XML documents that are instances of
* any of the schemas listed in the {@code contextPath}. For example:
*
* <pre>
* JAXBContext jc = JAXBContext.newInstance( "com.acme.foo:com.acme.bar" );
@@ -198,33 +198,42 @@
* used to compile the schema.
*
*
* <h3>Discovery of JAXB implementation</h3>
* <p>
- * When one of the {@code newInstance} methods is called, a JAXB implementation is discovered
- * by the following steps.
+ * To create an instance of {@link JAXBContext}, one of {@code JAXBContext.newInstance(...)} methods is invoked. After
+ * JAX-B implementation is discovered, call is delegated to appropriate provider's method {@code createContext(...)}
+ * passing parameters from the original call.
+ * <p>
+ * JAX-B implementation discovery happens each time {@code JAXBContext.newInstance} is invoked. If there is no user
+ * specific configuration provided, default JAX-B provider must be returned.
+ * <p>
+ * Implementation discovery consists of following steps:
*
* <ol>
*
* <li>
- * For each package/class explicitly passed in to the {@link #newInstance} method, in the order they are specified,
- * {@code jaxb.properties} file is looked up in its package, by using the associated classloader —
+ * Packages/classes explicitly passed in to the {@link #newInstance} method are processed in the order they are
+ * specified, until {@code jaxb.properties} file is looked up in its package, by using the associated classloader —
* this is {@link Class#getClassLoader() the owner class loader} for a {@link Class} argument, and for a package
* the specified {@link ClassLoader}.
*
* <p>
- * If such a file is discovered, it is {@link Properties#load(InputStream) loaded} as a property file, and
- * the value of the {@link #JAXB_CONTEXT_FACTORY} key will be assumed to be the provider factory class.
- * This class is then loaded by the associated class loader discussed above.
+ * If such a resource is discovered, it is {@link Properties#load(InputStream) loaded} as a property file, and
+ * the value of the {@link #JAXB_CONTEXT_FACTORY} key will be assumed to be the provider factory class. If no value
+ * found, {@code "javax.xml.bind.context.factory"} is used as a key for backwards compatibility reasons. This class is
+ * then loaded by the associated class loader discussed above.
*
* <p>
* This phase of the look up allows some packages to force the use of a certain JAXB implementation.
* (For example, perhaps the schema compiler has generated some vendor extension in the code.)
*
* <li>
* If the system property {@link #JAXB_CONTEXT_FACTORY} exists, then its value is assumed to be the provider
- * factory class. This phase of the look up enables per-JVM override of the JAXB implementation.
+ * factory class. If no such property exists, properties {@code "javax.xml.bind.context.factory"} and
+ * {@code "javax.xml.bind.JAXBContext"} are checked too (in this order), for backwards compatibility reasons. This phase
+ * of the look up enables per-JVM override of the JAXB implementation.
*
* <li>
* Provider of {@link javax.xml.bind.JAXBContextFactory} is loaded using the service-provider loading
* facilities, defined by the {@link java.util.ServiceLoader} class, to attempt
* to locate and load an implementation of the service using the {@linkplain
@@ -233,47 +242,62 @@
* to attempt to load the context factory. If the context class loader is null, the
* {@linkplain ClassLoader#getSystemClassLoader() system class loader} will be used.
* <br>
* In case of {@link java.util.ServiceConfigurationError service
* configuration error} a {@link javax.xml.bind.JAXBException} will be thrown.
- * </li>
*
* <li>
* Look for resource {@code /META-INF/services/javax.xml.bind.JAXBContext} using provided class loader.
* Methods without class loader parameter use {@code Thread.currentThread().getContextClassLoader()}.
- * If such a resource exists, its content is assumed to be the provider factory class and must supply
- * an implementation class containing the following method signatures:
+ * If such a resource exists, its content is assumed to be the provider factory class.
+ *
+ * This configuration method is deprecated.
+ *
+ * <li>
+ * Finally, if all the steps above fail, then the rest of the look up is unspecified. That said,
+ * the recommended behavior is to simply look for some hard-coded platform default JAXB implementation.
+ * This phase of the look up is so that JavaSE can have its own JAXB implementation as the last resort.
+ * </ol>
+ *
+ * <p>
+ * Once the provider factory class is discovered, context creation is delegated to one of its
+ * {@code createContext(...)} methods.
*
+ * For backward compatibility reasons, there are two ways how to implement provider factory class:
+ * <ol>
+ * <li>the class is implementation of {@link javax.xml.bind.JAXBContextFactory}. It must also implement no-arg
+ * constructor. If discovered in other step then 3, new instance using no-arg constructor is created first.
+ * After that, appropriate instance method is invoked on this instance.
+ * <li>the class is not implementation of interface above and then it is mandated to implement the following
+ * static method signatures:
* <pre>
*
* public static JAXBContext createContext(
* String contextPath,
* ClassLoader classLoader,
- * Map<String,Object> properties throws JAXBException
+ * Map<String,Object> properties ) throws JAXBException
*
* public static JAXBContext createContext(
* Class[] classes,
* Map<String,Object> properties ) throws JAXBException
* </pre>
- * This configuration method is deprecated.
- *
- * <li>
- * Finally, if all the steps above fail, then the rest of the look up is unspecified. That said,
- * the recommended behavior is to simply look for some hard-coded platform default JAXB implementation.
- * This phase of the look up is so that JavaSE can have its own JAXB implementation as the last resort.
+ * In this scenario, appropriate static method is used instead of instance method. This approach is incompatible
+ * with {@link java.util.ServiceLoader} so it can't be used with step 3.
* </ol>
- *
* <p>
- * Once the provider factory class {@link javax.xml.bind.JAXBContextFactory} is discovered, one of its methods
- * {@link javax.xml.bind.JAXBContextFactory#createContext(String, ClassLoader, java.util.Map)} or
- * {@link javax.xml.bind.JAXBContextFactory#createContext(Class[], java.util.Map)} is invoked
- * to create a {@link JAXBContext}.
+ * There is no difference in behavior of given method {@code createContext(...)} regardless of whether it uses approach
+ * 1 (JAXBContextFactory) or 2 (no interface, static methods).
*
* @apiNote
- * <p>Service discovery method using file /META-INF/services/javax.xml.bind.JAXBContext (described in step 4)
- * and leveraging provider's static methods is supported only to allow backwards compatibility, but it is strongly
- * recommended to migrate to standard ServiceLoader mechanism (described in step 3).
+ * Service discovery method using resource {@code /META-INF/services/javax.xml.bind.JAXBContext} (described in step 4)
+ * is supported only to allow backwards compatibility, it is strongly recommended to migrate to standard
+ * {@link java.util.ServiceLoader} mechanism (described in step 3). The difference here is the resource name, which
+ * doesn't match service's type name.
+ * <p>
+ * Also using providers implementing interface {@link JAXBContextFactory} is preferred over using ones defining
+ * static methods, same as {@link JAXBContext#JAXB_CONTEXT_FACTORY} property is preferred over property
+ * {@code "javax.xml.bind.context.factory"}
*
* @implNote
* Within the last step, if Glassfish AS environment detected, its specific service loader is used to find factory class.
*
* @author <ul><li>Ryan Shoemaker, Sun Microsystems, Inc.</li>
@@ -306,17 +330,11 @@
* This is a convenience method to invoke the
* {@link #newInstance(String,ClassLoader)} method with
* the context class loader of the current thread.
*
* @throws JAXBException if an error was encountered while creating the
- * {@code JAXBContext} such as
- * <ol>
- * <li>failure to locate either ObjectFactory.class or jaxb.index in the packages</li>
- * <li>an ambiguity among global elements contained in the contextPath</li>
- * <li>failure to locate a value for the context factory provider property</li>
- * <li>mixing schema derived packages from different providers on the same contextPath</li>
- * </ol>
+ * {@code JAXBContext}. See {@link JAXBContext#newInstance(String, ClassLoader, Map)} for details.
*/
public static JAXBContext newInstance( String contextPath )
throws JAXBException {
//return newInstance( contextPath, JAXBContext.class.getClassLoader() );
@@ -403,17 +421,11 @@
* This class loader will be used to locate the implementation
* classes.
*
* @return a new instance of a {@code JAXBContext}
* @throws JAXBException if an error was encountered while creating the
- * {@code JAXBContext} such as
- * <ol>
- * <li>failure to locate either ObjectFactory.class or jaxb.index in the packages</li>
- * <li>an ambiguity among global elements contained in the contextPath</li>
- * <li>failure to locate a value for the context factory provider property</li>
- * <li>mixing schema derived packages from different providers on the same contextPath</li>
- * </ol>
+ * {@code JAXBContext}. See {@link JAXBContext#newInstance(String, ClassLoader, Map)} for details.
*/
public static JAXBContext newInstance( String contextPath, ClassLoader classLoader ) throws JAXBException {
return newInstance(contextPath,classLoader,Collections.<String,Object>emptyMap());
}
@@ -425,11 +437,11 @@
* This is mostly the same as {@link JAXBContext#newInstance(String, ClassLoader)},
* but this version allows you to pass in provider-specific properties to configure
* the instantiation of {@link JAXBContext}.
*
* <p>
- * The interpretation of properties is up to implementations. Implementations should
+ * The interpretation of properties is up to implementations. Implementations must
* throw {@code JAXBException} if it finds properties that it doesn't understand.
*
* @param contextPath list of java package names that contain schema derived classes
* @param classLoader
* This class loader will be used to locate the implementation classes.
@@ -437,17 +449,11 @@
* provider-specific properties. Can be null, which means the same thing as passing
* in an empty map.
*
* @return a new instance of a {@code JAXBContext}
* @throws JAXBException if an error was encountered while creating the
- * {@code JAXBContext} such as
- * <ol>
- * <li>failure to locate either ObjectFactory.class or jaxb.index in the packages</li>
- * <li>an ambiguity among global elements contained in the contextPath</li>
- * <li>failure to locate a value for the context factory provider property</li>
- * <li>mixing schema derived packages from different providers on the same contextPath</li>
- * </ol>
+ * {@code JAXBContext}. See {@link #newInstance(String, ClassLoader)} for details.
* @since 1.6, JAXB 2.0
*/
public static JAXBContext newInstance( String contextPath,
ClassLoader classLoader,
Map<String,?> properties ) throws JAXBException {
@@ -581,21 +587,12 @@
* spec-defined classes will be returned.
*
* @return
* A new instance of a {@code JAXBContext}.
*
- * @throws JAXBException
- * if an error was encountered while creating the
- * {@code JAXBContext}, such as (but not limited to):
- * <ol>
- * <li>No JAXB implementation was discovered
- * <li>Classes use JAXB annotations incorrectly
- * <li>Classes have colliding annotations (i.e., two classes with the same type name)
- * <li>The JAXB implementation was unable to locate
- * provider-specific out-of-band information (such as additional
- * files generated at the development time.)
- * </ol>
+ * @throws JAXBException if an error was encountered while creating the
+ * {@code JAXBContext}. See {@link JAXBContext#newInstance(Class[], Map)} for details.
*
* @throws IllegalArgumentException
* if the parameter contains {@code null} (i.e., {@code newInstance(null);})
*
* @since 1.6, JAXB 2.0
@@ -612,11 +609,11 @@
* <p>
* An overloading of {@link JAXBContext#newInstance(Class...)}
* to configure 'properties' for this instantiation of {@link JAXBContext}.
*
* <p>
- * The interpretation of properties is up to implementations. Implementations should
+ * The interpretation of properties is up to implementations. Implementations must
* throw {@code JAXBException} if it finds properties that it doesn't understand.
*
* @param classesToBeBound
* list of java classes to be recognized by the new {@link JAXBContext}.
* Can be empty, in which case a {@link JAXBContext} that only knows about
< prev index next >