这个程序:
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());
}
}
为第一个和第二个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此上下文已知的类:[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-r t-2.0.1.jar!/com/sun/xml/bind/v2/runtime/JAXBContextImpl.class Build-Id:1.0此上下文已知的类:[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
然而,ClassSpecificallyIncluded位于foo.bar.baz包中:
//
// 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 {...
两个JAXBContexts的类路径和类加载器都是相同的 .
那么为什么第二个JAXBContext不知道ClassSpecificallyIncluded?
2 回答
您的问题的答案在这里得到了有效的回答:
Can you find all classes in a package using reflection?
Answer: 否按设计,java不会查找包中的每个类 . Java Build 在"Just in time"的概念之上 . 对于这个目的而言,这意味着java在获得特定内容之前不会获得 .
所以从这个角度来看,JAXB无法找到包中的类 .
如果每次需要上下文时都必须准确地告知每个 class ,那将是不方便的 . 因此,作为一种便捷方法,JAXB为您提供了提供包名称的选项 .
为了绕过java的限制,它试图从该包加载
ObjectFactory
和jaxb.index
文件 . 它可以这样做,因为它们是特定的名称 . 如果找到一个,那么它将它们用作包的清单 . 如果两者都找不到它,则除了中止之外别无选择,因为它可以在包中找到't possibly know what' .在包名称上创建JAXBContext
假设我在名为
forum20273355
的目录中有以下类:地址
客户(延伸人)
哺乳动物
Person(扩展Mammal并具有Address类型的属性)
如果我使用以下代码创建
JAXBContext
:然后我会得到以下异常:
指定jaxb.index或ObjectFactory
下面我们将创建一个
jaxb.index
文件和ObjectFactory
,这将导致Person
类被处理以查看会发生什么 .jaxb.index
jaxb.index
是一个文本文件,其中包含一个回车分隔的短类名列表 .ObjectFactory
Processed Classes
显然
Person
已被处理,但超类Mammal
和引用类Address
也是如此 . 未处理的类是子类Customer
.获取已处理的子类
显然我们可以将子类
Customer
添加到jaxb.index
或ObjectFactory
. 我们还可以利用@XmlSeeAlso
注释来实现这一目标 .现在
Customer
也被处理了 .更新
你在评论中写的一切都是真的 . 缺少的是
jaxb.index
文件或ObjectFactory
类需要踢这个过程 . 从XML模式生成模型时,会生成ObjectFactory
,其中包含引导模型的所有必要引用 . 当您从Java类开始时,我建议从Java类而不是包名称引导,但适用相同的规则 .没错,包名称指定了要查找元数据的位置 .
真正 .
没错,肯定会应用包注释 .