jaxws/src/java.xml.bind/share/classes/javax/xml/bind/JAXBContext.java
changeset 35414 59fc48a1a885
parent 31501 1b48499c9e1c
child 36033 f50f6572da23
equal deleted inserted replaced
35413:56a695bbebe8 35414:59fc48a1a885
     1 /*
     1 /*
     2  * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
     2  * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.  Oracle designates this
     7  * published by the Free Software Foundation.  Oracle designates this
    92  * the schema  to be unmarshalled as the root of an instance document.
    92  * the schema  to be unmarshalled as the root of an instance document.
    93  * The {@code JAXBContext} object
    93  * The {@code JAXBContext} object
    94  * allows the merging of global elements and type definitions across a set of schemas (listed
    94  * allows the merging of global elements and type definitions across a set of schemas (listed
    95  * in the {@code contextPath}). Since each schema in the schema set can belong
    95  * in the {@code contextPath}). Since each schema in the schema set can belong
    96  * to distinct namespaces, the unification of schemas to an unmarshalling
    96  * to distinct namespaces, the unification of schemas to an unmarshalling
    97  * context should be namespace independent.  This means that a client
    97  * context must be namespace independent.  This means that a client
    98  * application is able to unmarshal XML documents that are instances of
    98  * application is able to unmarshal XML documents that are instances of
    99  * any of the schemas listed in the {@code contextPath}.  For example:
    99  * any of the schemas listed in the {@code contextPath}.  For example:
   100  *
   100  *
   101  * <pre>
   101  * <pre>
   102  *      JAXBContext jc = JAXBContext.newInstance( "com.acme.foo:com.acme.bar" );
   102  *      JAXBContext jc = JAXBContext.newInstance( "com.acme.foo:com.acme.bar" );
   198  * used to compile the schema.
   198  * used to compile the schema.
   199  *
   199  *
   200  *
   200  *
   201  * <h3>Discovery of JAXB implementation</h3>
   201  * <h3>Discovery of JAXB implementation</h3>
   202  * <p>
   202  * <p>
   203  * When one of the {@code newInstance} methods is called, a JAXB implementation is discovered
   203  * To create an instance of {@link JAXBContext}, one of {@code JAXBContext.newInstance(...)} methods is invoked. After
   204  * by the following steps.
   204  * JAX-B implementation is discovered, call is delegated to appropriate provider's method {@code createContext(...)}
       
   205  * passing parameters from the original call.
       
   206  * <p>
       
   207  * JAX-B implementation discovery happens each time {@code JAXBContext.newInstance} is invoked. If there is no user
       
   208  * specific configuration provided, default JAX-B provider must be returned.
       
   209  * <p>
       
   210  * Implementation discovery consists of following steps:
   205  *
   211  *
   206  * <ol>
   212  * <ol>
   207  *
   213  *
   208  * <li>
   214  * <li>
   209  * For each package/class explicitly passed in to the {@link #newInstance} method, in the order they are specified,
   215  * Packages/classes explicitly passed in to the {@link #newInstance} method are processed in the order they are
   210  * {@code jaxb.properties} file is looked up in its package, by using the associated classloader &mdash;
   216  * specified, until {@code jaxb.properties} file is looked up in its package, by using the associated classloader &mdash;
   211  * this is {@link Class#getClassLoader() the owner class loader} for a {@link Class} argument, and for a package
   217  * this is {@link Class#getClassLoader() the owner class loader} for a {@link Class} argument, and for a package
   212  * the specified {@link ClassLoader}.
   218  * the specified {@link ClassLoader}.
   213  *
   219  *
   214  * <p>
   220  * <p>
   215  * If such a file is discovered, it is {@link Properties#load(InputStream) loaded} as a property file, and
   221  * If such a resource is discovered, it is {@link Properties#load(InputStream) loaded} as a property file, and
   216  * the value of the {@link #JAXB_CONTEXT_FACTORY} key will be assumed to be the provider factory class.
   222  * the value of the {@link #JAXB_CONTEXT_FACTORY} key will be assumed to be the provider factory class. If no value
   217  * This class is then loaded by the associated class loader discussed above.
   223  * found, {@code "javax.xml.bind.context.factory"} is used as a key for backwards compatibility reasons. This class is
       
   224  * then loaded by the associated class loader discussed above.
   218  *
   225  *
   219  * <p>
   226  * <p>
   220  * This phase of the look up allows some packages to force the use of a certain JAXB implementation.
   227  * This phase of the look up allows some packages to force the use of a certain JAXB implementation.
   221  * (For example, perhaps the schema compiler has generated some vendor extension in the code.)
   228  * (For example, perhaps the schema compiler has generated some vendor extension in the code.)
   222  *
   229  *
   223  * <li>
   230  * <li>
   224  * If the system property {@link #JAXB_CONTEXT_FACTORY} exists, then its value is assumed to be the provider
   231  * If the system property {@link #JAXB_CONTEXT_FACTORY} exists, then its value is assumed to be the provider
   225  * factory class. This phase of the look up enables per-JVM override of the JAXB implementation.
   232  * factory class. If no such property exists, properties {@code "javax.xml.bind.context.factory"} and
       
   233  * {@code "javax.xml.bind.JAXBContext"} are checked too (in this order), for backwards compatibility reasons. This phase
       
   234  * of the look up enables per-JVM override of the JAXB implementation.
   226  *
   235  *
   227  * <li>
   236  * <li>
   228  * Provider of {@link javax.xml.bind.JAXBContextFactory} is loaded using the service-provider loading
   237  * Provider of {@link javax.xml.bind.JAXBContextFactory} is loaded using the service-provider loading
   229  * facilities, defined by the {@link java.util.ServiceLoader} class, to attempt
   238  * facilities, defined by the {@link java.util.ServiceLoader} class, to attempt
   230  * to locate and load an implementation of the service using the {@linkplain
   239  * to locate and load an implementation of the service using the {@linkplain
   233  * to attempt to load the context factory. If the context class loader is null, the
   242  * to attempt to load the context factory. If the context class loader is null, the
   234  * {@linkplain ClassLoader#getSystemClassLoader() system class loader} will be used.
   243  * {@linkplain ClassLoader#getSystemClassLoader() system class loader} will be used.
   235  * <br>
   244  * <br>
   236  * In case of {@link java.util.ServiceConfigurationError service
   245  * In case of {@link java.util.ServiceConfigurationError service
   237  * configuration error} a {@link javax.xml.bind.JAXBException} will be thrown.
   246  * configuration error} a {@link javax.xml.bind.JAXBException} will be thrown.
   238  * </li>
       
   239  *
   247  *
   240  * <li>
   248  * <li>
   241  * Look for resource {@code /META-INF/services/javax.xml.bind.JAXBContext} using provided class loader.
   249  * Look for resource {@code /META-INF/services/javax.xml.bind.JAXBContext} using provided class loader.
   242  * Methods without class loader parameter use {@code Thread.currentThread().getContextClassLoader()}.
   250  * Methods without class loader parameter use {@code Thread.currentThread().getContextClassLoader()}.
   243  * If such a resource exists, its content is assumed to be the provider factory class and must supply
   251  * If such a resource exists, its content is assumed to be the provider factory class.
   244  * an implementation class containing the following method signatures:
   252  *
   245  *
   253  * This configuration method is deprecated.
       
   254  *
       
   255  * <li>
       
   256  * Finally, if all the steps above fail, then the rest of the look up is unspecified. That said,
       
   257  * the recommended behavior is to simply look for some hard-coded platform default JAXB implementation.
       
   258  * This phase of the look up is so that Java SE can have its own JAXB implementation as the last resort.
       
   259  * </ol>
       
   260  *
       
   261  * <p>
       
   262  * Once the provider factory class is discovered, context creation is delegated to one of its
       
   263  * {@code createContext(...)} methods.
       
   264  *
       
   265  * For backward compatibility reasons, there are two ways how to implement provider factory class:
       
   266  * <ol>
       
   267  *     <li>the class is implementation of {@link javax.xml.bind.JAXBContextFactory}. It must also implement no-arg
       
   268  *     constructor. If discovered in other step then 3, new instance using no-arg constructor is created first.
       
   269  *     After that, appropriate instance method is invoked on this instance.
       
   270  *     <li>the class is not implementation of interface above and then it is mandated to implement the following
       
   271  *     static method signatures:
   246  * <pre>
   272  * <pre>
   247  *
   273  *
   248  * public static JAXBContext createContext(
   274  * public static JAXBContext createContext(
   249  *                                      String contextPath,
   275  *                                      String contextPath,
   250  *                                      ClassLoader classLoader,
   276  *                                      ClassLoader classLoader,
   251  *                                      Map&lt;String,Object&gt; properties throws JAXBException
   277  *                                      Map&lt;String,Object&gt; properties ) throws JAXBException
   252  *
   278  *
   253  * public static JAXBContext createContext(
   279  * public static JAXBContext createContext(
   254  *                                      Class[] classes,
   280  *                                      Class[] classes,
   255  *                                      Map&lt;String,Object&gt; properties ) throws JAXBException
   281  *                                      Map&lt;String,Object&gt; properties ) throws JAXBException
   256  * </pre>
   282  * </pre>
   257  * This configuration method is deprecated.
   283  *      In this scenario, appropriate static method is used instead of instance method. This approach is incompatible
   258  *
   284  *      with {@link java.util.ServiceLoader} so it can't be used with step 3.
   259  * <li>
       
   260  * Finally, if all the steps above fail, then the rest of the look up is unspecified. That said,
       
   261  * the recommended behavior is to simply look for some hard-coded platform default JAXB implementation.
       
   262  * This phase of the look up is so that JavaSE can have its own JAXB implementation as the last resort.
       
   263  * </ol>
   285  * </ol>
   264  *
   286  * <p>
   265  * <p>
   287  * There is no difference in behavior of given method {@code createContext(...)} regardless of whether it uses approach
   266  * Once the provider factory class {@link javax.xml.bind.JAXBContextFactory} is discovered, one of its methods
   288  * 1 (JAXBContextFactory) or 2 (no interface, static methods).
   267  * {@link javax.xml.bind.JAXBContextFactory#createContext(String, ClassLoader, java.util.Map)} or
       
   268  * {@link javax.xml.bind.JAXBContextFactory#createContext(Class[], java.util.Map)} is invoked
       
   269  * to create a {@link JAXBContext}.
       
   270  *
   289  *
   271  * @apiNote
   290  * @apiNote
   272  * <p>Service discovery method using file /META-INF/services/javax.xml.bind.JAXBContext (described in step 4)
   291  * Service discovery method using resource {@code /META-INF/services/javax.xml.bind.JAXBContext} (described in step 4)
   273  * and leveraging provider's static methods is supported only to allow backwards compatibility, but it is strongly
   292  * is supported only to allow backwards compatibility, it is strongly recommended to migrate to standard
   274  * recommended to migrate to standard ServiceLoader mechanism (described in step 3).
   293  * {@link java.util.ServiceLoader} mechanism (described in step 3). The difference here is the resource name, which
       
   294  * doesn't match service's type name.
       
   295  * <p>
       
   296  * Also using providers implementing interface {@link JAXBContextFactory} is preferred over using ones defining
       
   297  * static methods, same as {@link JAXBContext#JAXB_CONTEXT_FACTORY} property is preferred over property
       
   298  * {@code "javax.xml.bind.context.factory"}
   275  *
   299  *
   276  * @implNote
   300  * @implNote
   277  * Within the last step, if Glassfish AS environment detected, its specific service loader is used to find factory class.
   301  * Within the last step, if Glassfish AS environment detected, its specific service loader is used to find factory class.
   278  *
   302  *
   279  * @author <ul><li>Ryan Shoemaker, Sun Microsystems, Inc.</li>
   303  * @author <ul><li>Ryan Shoemaker, Sun Microsystems, Inc.</li>
   306      * This is a convenience method to invoke the
   330      * This is a convenience method to invoke the
   307      * {@link #newInstance(String,ClassLoader)} method with
   331      * {@link #newInstance(String,ClassLoader)} method with
   308      * the context class loader of the current thread.
   332      * the context class loader of the current thread.
   309      *
   333      *
   310      * @throws JAXBException if an error was encountered while creating the
   334      * @throws JAXBException if an error was encountered while creating the
   311      *                       {@code JAXBContext} such as
   335      *               {@code JAXBContext}. See {@link JAXBContext#newInstance(String, ClassLoader, Map)} for details.
   312      * <ol>
       
   313      *   <li>failure to locate either ObjectFactory.class or jaxb.index in the packages</li>
       
   314      *   <li>an ambiguity among global elements contained in the contextPath</li>
       
   315      *   <li>failure to locate a value for the context factory provider property</li>
       
   316      *   <li>mixing schema derived packages from different providers on the same contextPath</li>
       
   317      * </ol>
       
   318      */
   336      */
   319     public static JAXBContext newInstance( String contextPath )
   337     public static JAXBContext newInstance( String contextPath )
   320         throws JAXBException {
   338             throws JAXBException {
   321 
   339 
   322         //return newInstance( contextPath, JAXBContext.class.getClassLoader() );
   340         //return newInstance( contextPath, JAXBContext.class.getClassLoader() );
   323         return newInstance( contextPath, getContextClassLoader());
   341         return newInstance( contextPath, getContextClassLoader());
   324     }
   342     }
   325 
   343 
   403      *      This class loader will be used to locate the implementation
   421      *      This class loader will be used to locate the implementation
   404      *      classes.
   422      *      classes.
   405      *
   423      *
   406      * @return a new instance of a {@code JAXBContext}
   424      * @return a new instance of a {@code JAXBContext}
   407      * @throws JAXBException if an error was encountered while creating the
   425      * @throws JAXBException if an error was encountered while creating the
   408      *                       {@code JAXBContext} such as
   426      *               {@code JAXBContext}. See {@link JAXBContext#newInstance(String, ClassLoader, Map)} for details.
   409      * <ol>
       
   410      *   <li>failure to locate either ObjectFactory.class or jaxb.index in the packages</li>
       
   411      *   <li>an ambiguity among global elements contained in the contextPath</li>
       
   412      *   <li>failure to locate a value for the context factory provider property</li>
       
   413      *   <li>mixing schema derived packages from different providers on the same contextPath</li>
       
   414      * </ol>
       
   415      */
   427      */
   416     public static JAXBContext newInstance( String contextPath, ClassLoader classLoader ) throws JAXBException {
   428     public static JAXBContext newInstance( String contextPath, ClassLoader classLoader ) throws JAXBException {
   417 
   429 
   418         return newInstance(contextPath,classLoader,Collections.<String,Object>emptyMap());
   430         return newInstance(contextPath,classLoader,Collections.<String,Object>emptyMap());
   419     }
   431     }
   425      * This is mostly the same as {@link JAXBContext#newInstance(String, ClassLoader)},
   437      * This is mostly the same as {@link JAXBContext#newInstance(String, ClassLoader)},
   426      * but this version allows you to pass in provider-specific properties to configure
   438      * but this version allows you to pass in provider-specific properties to configure
   427      * the instantiation of {@link JAXBContext}.
   439      * the instantiation of {@link JAXBContext}.
   428      *
   440      *
   429      * <p>
   441      * <p>
   430      * The interpretation of properties is up to implementations. Implementations should
   442      * The interpretation of properties is up to implementations. Implementations must
   431      * throw {@code JAXBException} if it finds properties that it doesn't understand.
   443      * throw {@code JAXBException} if it finds properties that it doesn't understand.
   432      *
   444      *
   433      * @param contextPath list of java package names that contain schema derived classes
   445      * @param contextPath list of java package names that contain schema derived classes
   434      * @param classLoader
   446      * @param classLoader
   435      *      This class loader will be used to locate the implementation classes.
   447      *      This class loader will be used to locate the implementation classes.
   437      *      provider-specific properties. Can be null, which means the same thing as passing
   449      *      provider-specific properties. Can be null, which means the same thing as passing
   438      *      in an empty map.
   450      *      in an empty map.
   439      *
   451      *
   440      * @return a new instance of a {@code JAXBContext}
   452      * @return a new instance of a {@code JAXBContext}
   441      * @throws JAXBException if an error was encountered while creating the
   453      * @throws JAXBException if an error was encountered while creating the
   442      *                       {@code JAXBContext} such as
   454      *                       {@code JAXBContext}. See {@link #newInstance(String, ClassLoader)} for details.
   443      * <ol>
       
   444      *   <li>failure to locate either ObjectFactory.class or jaxb.index in the packages</li>
       
   445      *   <li>an ambiguity among global elements contained in the contextPath</li>
       
   446      *   <li>failure to locate a value for the context factory provider property</li>
       
   447      *   <li>mixing schema derived packages from different providers on the same contextPath</li>
       
   448      * </ol>
       
   449      * @since 1.6, JAXB 2.0
   455      * @since 1.6, JAXB 2.0
   450      */
   456      */
   451     public static JAXBContext newInstance( String contextPath,
   457     public static JAXBContext newInstance( String contextPath,
   452                                            ClassLoader classLoader,
   458                                            ClassLoader classLoader,
   453                                            Map<String,?>  properties  ) throws JAXBException {
   459                                            Map<String,?>  properties  ) throws JAXBException {
   454 
   460 
   455         return ContextFinder.find(
   461         return ContextFinder.find(
   456                         /* The default property name according to the JAXB spec */
   462                         /* The default property name according to the JAXB spec */
   457                         JAXB_CONTEXT_FACTORY,
   463                 JAXB_CONTEXT_FACTORY,
   458 
   464 
   459                         /* the context path supplied by the client app */
   465                         /* the context path supplied by the client app */
   460                         contextPath,
   466                 contextPath,
   461 
   467 
   462                         /* class loader to be used */
   468                         /* class loader to be used */
   463                         classLoader,
   469                 classLoader,
   464                         properties );
   470                 properties );
   465     }
   471     }
   466 
   472 
   467 // TODO: resurrect this once we introduce external annotations
   473 // TODO: resurrect this once we introduce external annotations
   468 //    /**
   474 //    /**
   469 //     * Create a new instance of a {@code JAXBContext} class.
   475 //     * Create a new instance of a {@code JAXBContext} class.
   581      *      spec-defined classes will be returned.
   587      *      spec-defined classes will be returned.
   582      *
   588      *
   583      * @return
   589      * @return
   584      *      A new instance of a {@code JAXBContext}.
   590      *      A new instance of a {@code JAXBContext}.
   585      *
   591      *
       
   592      * @throws JAXBException if an error was encountered while creating the
       
   593      *               {@code JAXBContext}. See {@link JAXBContext#newInstance(Class[], Map)} for details.
       
   594      *
       
   595      * @throws IllegalArgumentException
       
   596      *      if the parameter contains {@code null} (i.e., {@code newInstance(null);})
       
   597      *
       
   598      * @since 1.6, JAXB 2.0
       
   599      */
       
   600     public static JAXBContext newInstance( Class<?> ... classesToBeBound )
       
   601             throws JAXBException {
       
   602 
       
   603         return newInstance(classesToBeBound,Collections.<String,Object>emptyMap());
       
   604     }
       
   605 
       
   606     /**
       
   607      * Create a new instance of a {@code JAXBContext} class.
       
   608      *
       
   609      * <p>
       
   610      * An overloading of {@link JAXBContext#newInstance(Class...)}
       
   611      * to configure 'properties' for this instantiation of {@link JAXBContext}.
       
   612      *
       
   613      * <p>
       
   614      * The interpretation of properties is up to implementations. Implementations must
       
   615      * throw {@code JAXBException} if it finds properties that it doesn't understand.
       
   616      *
       
   617      * @param classesToBeBound
       
   618      *      list of java classes to be recognized by the new {@link JAXBContext}.
       
   619      *      Can be empty, in which case a {@link JAXBContext} that only knows about
       
   620      *      spec-defined classes will be returned.
       
   621      * @param properties
       
   622      *      provider-specific properties. Can be null, which means the same thing as passing
       
   623      *      in an empty map.
       
   624      *
       
   625      * @return
       
   626      *      A new instance of a {@code JAXBContext}.
       
   627      *
   586      * @throws JAXBException
   628      * @throws JAXBException
   587      *      if an error was encountered while creating the
   629      *      if an error was encountered while creating the
   588      *      {@code JAXBContext}, such as (but not limited to):
   630      *      {@code JAXBContext}, such as (but not limited to):
   589      * <ol>
   631      * <ol>
   590      *  <li>No JAXB implementation was discovered
   632      *  <li>No JAXB implementation was discovered
   594      *      provider-specific out-of-band information (such as additional
   636      *      provider-specific out-of-band information (such as additional
   595      *      files generated at the development time.)
   637      *      files generated at the development time.)
   596      * </ol>
   638      * </ol>
   597      *
   639      *
   598      * @throws IllegalArgumentException
   640      * @throws IllegalArgumentException
   599      *      if the parameter contains {@code null} (i.e., {@code newInstance(null);})
   641      *      if the parameter contains {@code null} (i.e., {@code newInstance(null,someMap);})
   600      *
   642      *
   601      * @since 1.6, JAXB 2.0
   643      * @since 1.6, JAXB 2.0
   602      */
   644      */
   603     public static JAXBContext newInstance( Class<?> ... classesToBeBound )
       
   604         throws JAXBException {
       
   605 
       
   606         return newInstance(classesToBeBound,Collections.<String,Object>emptyMap());
       
   607     }
       
   608 
       
   609     /**
       
   610      * Create a new instance of a {@code JAXBContext} class.
       
   611      *
       
   612      * <p>
       
   613      * An overloading of {@link JAXBContext#newInstance(Class...)}
       
   614      * to configure 'properties' for this instantiation of {@link JAXBContext}.
       
   615      *
       
   616      * <p>
       
   617      * The interpretation of properties is up to implementations. Implementations should
       
   618      * throw {@code JAXBException} if it finds properties that it doesn't understand.
       
   619      *
       
   620      * @param classesToBeBound
       
   621      *      list of java classes to be recognized by the new {@link JAXBContext}.
       
   622      *      Can be empty, in which case a {@link JAXBContext} that only knows about
       
   623      *      spec-defined classes will be returned.
       
   624      * @param properties
       
   625      *      provider-specific properties. Can be null, which means the same thing as passing
       
   626      *      in an empty map.
       
   627      *
       
   628      * @return
       
   629      *      A new instance of a {@code JAXBContext}.
       
   630      *
       
   631      * @throws JAXBException
       
   632      *      if an error was encountered while creating the
       
   633      *      {@code JAXBContext}, such as (but not limited to):
       
   634      * <ol>
       
   635      *  <li>No JAXB implementation was discovered
       
   636      *  <li>Classes use JAXB annotations incorrectly
       
   637      *  <li>Classes have colliding annotations (i.e., two classes with the same type name)
       
   638      *  <li>The JAXB implementation was unable to locate
       
   639      *      provider-specific out-of-band information (such as additional
       
   640      *      files generated at the development time.)
       
   641      * </ol>
       
   642      *
       
   643      * @throws IllegalArgumentException
       
   644      *      if the parameter contains {@code null} (i.e., {@code newInstance(null,someMap);})
       
   645      *
       
   646      * @since 1.6, JAXB 2.0
       
   647      */
       
   648     public static JAXBContext newInstance( Class<?>[] classesToBeBound, Map<String,?> properties )
   645     public static JAXBContext newInstance( Class<?>[] classesToBeBound, Map<String,?> properties )
   649         throws JAXBException {
   646             throws JAXBException {
   650 
   647 
   651         if (classesToBeBound == null) {
   648         if (classesToBeBound == null) {
   652                 throw new IllegalArgumentException();
   649             throw new IllegalArgumentException();
   653         }
   650         }
   654 
   651 
   655         // but it is an error to have nulls in it.
   652         // but it is an error to have nulls in it.
   656         for (int i = classesToBeBound.length - 1; i >= 0; i--) {
   653         for (int i = classesToBeBound.length - 1; i >= 0; i--) {
   657             if (classesToBeBound[i] == null) {
   654             if (classesToBeBound[i] == null) {