Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
427 views
in Technique[技术] by (71.8m points)

jaxb - Why does JAXBContext need to be told specifically about a class that is already in the package?

This program:

import foo.bar.baz.ClassSpecificallyIncluded;  
import javax.xml.bind.JAXBContext;  
public class A {  
    public static void main(String[] args) throws Exception {  
        System.out.println(JAXBContext.newInstance(ClassSpecificallyIncluded.class).toString());  
        System.out.println(JAXBContext.newInstance("foo.bar.baz").toString());  
    }  
}  

produces different output for the first and second JAXBContext:

jar:file:/C:/dev/trunk/rt/tomcat/shared/lib/webservices-rt-2.0.1.jar!/com/sun/xml/bind/v2/runtime/JAXBContextImpl.class Build-Id: 1.0
Classes known to this context:
[B
boolean
byte
char
foo.bar.baz.Class1
foo.bar.baz.Class1$NestedClass
foo.bar.baz.Class2
foo.bar.baz.ClassSpecificallyIncluded
foo.bar.baz.AnotherClass
com.sun.xml.bind.api.CompositeStructure
double
float
int
java.awt.Image
java.io.File
java.lang.Boolean
java.lang.Byte
java.lang.Character
java.lang.Class
java.lang.Double
java.lang.Float
java.lang.Integer
java.lang.Long
java.lang.Object
java.lang.Short
java.lang.String
java.lang.Void
java.math.BigDecimal
java.math.BigInteger
java.net.URI
java.net.URL
java.util.Calendar
java.util.Date
java.util.GregorianCalendar
java.util.UUID
javax.activation.DataHandler
javax.xml.bind.JAXBElement
javax.xml.datatype.Duration
javax.xml.datatype.XMLGregorianCalendar
javax.xml.namespace.QName
javax.xml.transform.Source
long
short
void

jar:file:/C:/dev/trunk/rt/tomcat/shared/lib/webservices-rt-2.0.1.jar!/com/sun/xml/bind/v2/runtime/JAXBContextImpl.class Build-Id: 1.0
Classes known to this context:
[B
boolean
byte
char
foo.bar.baz.Class1
foo.bar.baz.Class1$NestedClass
foo.bar.baz.Class2
<<< CLASS IS MISSING HERE>>>
foo.bar.baz.AnotherClass
com.sun.xml.bind.api.CompositeStructure
double
float
int
java.awt.Image
java.io.File
java.lang.Boolean
java.lang.Byte
java.lang.Character
java.lang.Class
java.lang.Double
java.lang.Float
java.lang.Integer
java.lang.Long
java.lang.Object
java.lang.Short
java.lang.String
java.lang.Void
java.math.BigDecimal
java.math.BigInteger
java.net.URI
java.net.URL
java.util.Calendar
java.util.Date
java.util.GregorianCalendar
java.util.UUID
javax.activation.DataHandler
javax.xml.bind.JAXBElement
javax.xml.datatype.Duration
javax.xml.datatype.XMLGregorianCalendar
javax.xml.namespace.QName
javax.xml.transform.Source
long
short
void

And yet, ClassSpecificallyIncluded is in the foo.bar.baz package:

//  
// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vJAXB 2.1.10 in JDK 6   
// See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a>   
// Any modifications to this file will be lost upon recompilation of the source schema.   
// Generated on: 2012.05.14 at 10:47:17 PM IST   
//  

package foo.bar.baz;  

import javax.xml.bind.annotation.XmlAccessType;  
import javax.xml.bind.annotation.XmlAccessorType;  
import javax.xml.bind.annotation.XmlElement;  
import javax.xml.bind.annotation.XmlRootElement;  


@XmlAccessorType(XmlAccessType.FIELD)  
@XmlType(name = "", propOrder = {  
    "applicationArea",  
    "dataArea"  
})  
@XmlRootElement(name = "ClassSpecificallyIncluded")  
public class ClassSpecificallyIncluded {...  

The classpath and classloader are the same for both JAXBContexts.

So why doesn’t the second JAXBContext know about ClassSpecificallyIncluded?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The answer to your question is effectively answered here:

Can you find all classes in a package using reflection?

Answer: No By design, java doesn't know and can't find every class in a package. Java is built on the concept of "Just in time". Which for this purpose means that java doesn't know what it's got until it's asked for something specifically.

So from that stand point, JAXB has no way to find what classes are in a package.

It would be inconvenient if JAXB had to be told precisely every class every time you needed context. So as a convenience method JAXB offers you the option of providing a package name.

In order to get round the limitations of java it attempts to load from that package an ObjectFactory and a jaxb.index file. It can do this because they are specific names. If one is found, then it uses them as a manifest for the package. If neither is found it has no option but to abort because it can't possibly know what's in the package.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...