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 — |
216 * specified, until {@code jaxb.properties} file is looked up in its package, by using the associated classloader — |
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<String,Object> properties throws JAXBException |
277 * Map<String,Object> properties ) throws JAXBException |
252 * |
278 * |
253 * public static JAXBContext createContext( |
279 * public static JAXBContext createContext( |
254 * Class[] classes, |
280 * Class[] classes, |
255 * Map<String,Object> properties ) throws JAXBException |
281 * Map<String,Object> 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 } |
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) { |