它就在那里,在包中,它应该是索引。 不过,当我打电话
JAXBContext jc = JAXBContext.newInstance("my.package.name");
我得到一个JAXBException说,
“my.package.name”犯规含有ObjectFactory.class或jaxb.index
虽然它同时包含。
这是什么工作,但不是很我想要的,是
JAXBContext jc = JAXBContext.newInstance(my.package.name.SomeClass.class);
这从各种其他人的问题出现在相当长的一段邮件列表和论坛,但似乎并没有得到答案。
我在OpenJDK的6运行这一点,所以我得到了源代码包,走到我的调试器到库中。 它开始通过寻找jaxb.properties,然后查找系统属性和没有找到任何,它试图创建使用com.sun.internal.xml.bind.v2.ContextFactory默认的上下文。 在那里,异常得到投掷(内ContextFactor.createContext(String ClassLoader, Map)
),但我看不到发生了什么事情,因为源不在这里。
AND:
从ContentFactory的源代码来看,我发现在这里 ,这可能是一段代码,无法按预期工作:
/**
* Look for jaxb.index file in the specified package and load it's contents
*
* @param pkg package name to search in
* @param classLoader ClassLoader to search in
* @return a List of Class objects to load, null if there weren't any
* @throws IOException if there is an error reading the index file
* @throws JAXBException if there are any errors in the index file
*/
private static List<Class> loadIndexedClasses(String pkg, ClassLoader classLoader) throws IOException, JAXBException {
final String resource = pkg.replace('.', '/') + "/jaxb.index";
final InputStream resourceAsStream = classLoader.getResourceAsStream(resource);
if (resourceAsStream == null) {
return null;
}
从我以往 的经验 ,我猜,这与这是运行OSGi容器的类加载机制做的。不幸的是,我还是有点在这里我的深度。
Answer 1:
OK,这花了一段挖,但答案并不令人惊奇甚至没有那么复杂:
JAXB找不到jaxb.index,因为默认情况下, newInstance(String)
使用当前线程的类加载器(由返回的Thread.getContextClassLoader()
这并不里面菲利克斯工作,因为OSGi包和框架的线程有独立的类加载器。
解决的办法是从什么地方得到一个合适的类加载器,并使用newInstance(String, ClassLoader)
。 我有一个合适的类加载器中包含包中的类的一个jaxb.index
,灵活性原因明智的选择可能是ObjectFactory
:
ClassLoader cl = my.package.name.ObjectFactory.class.getClassLoader();
JAXBContext jc = JAXBContext.newInstance("my.package.name", cl);
也许你也可以得到在该的类加载器Bundle
实例使用,但我无法弄清楚如何,以及上述方案似乎还给我。
Answer 2:
我面对我的工作项目类似的问题。 看完后http://jaxb.java.net/faq/index.html#classloader我意识到JAXBContext而无法找到包含jaxb.index包。
我将努力使这一尽可能明确。
我们有
Bundle A
-- com.a
A.java
aMethod()
{
B.bMethod("com.c.C");
}
MANIFEST.MF
Import-Package: com.b, com.c
Bundle B
-- com.b
B.java
bmethod(String className)
{
Class clazz = Class.forName(className);
}
Export-Package: com.b
Bundle C
-- com.c
C.java
c()
{
System.out.println("hello i am C");
}
Export-Package: com.c
涉及到JAXB。 类B是的JAXBContext和bMethod是的newInstance()
如果您熟悉的OSGi包的限制,那么它必须很清楚,现在包B未导入包com.c即C类是没有 B类 可见 ,因此它无法实例C.
该解决方案将是一个ClassLoader传递给bMethod。 这个类加载器应来自被导入com.c捆绑 。 在这种情况下,我们可以通过A.class.getClassLoader(),因为束A被导入com.c
希望这是有益的。
Answer 3:
Answer 4:
如果你在你的项目中使用maven,那么就使用这个库:
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-osgi</artifactId>
<version>2.2.7</version>
</dependency>
它为Glasfish服务器创建的,但也与Tomcat的工作(检查)。 有了这个库,你可以使用伊斯利与JAXB OSGi包。
Answer 5:
编辑2:
我曾经在我的应用程序也有类似的奇怪的类加载问题。 如果我运行它作为一个正常的应用程序,一切OK了,但是当我调用它作为Windows服务,它开始失败,ClassNotFoundExceptions。 分析表明,该线程有自己的类加载器为空莫名其妙。 我通过对线程设置SystemClassLoader解决了这个问题:
// ...
thread.setContextClassLoader(ClassLoader.getSystemClassLoader());
thread.start();
// ...
不知道,如果你的容器允许这种变化虽然。
Answer 6:
我刚刚碰到这个问题。 对我来说,解决方案是使用IBM的JRE,而不是甲骨文。 好像JAXB实现是在一个更OSGI友好。
Answer 7:
我通过添加含有我生成的类的包成功地解决了这个ObjectFactory
到<Private-Package>
我的束的定义,加的一部分org.jvnet.jaxb2_commons.*
Answer 8:
有可能是另一种情形,可以给这个问题。
当您安装并启动其导出包含jaxb.index或objectFactory.java包捆绑
然后请确保输入类的包被停止或指向正确的包名。
还要检查在pom.xml导出和导入语句
在ServiceMix的(karaf)OSGi容器也面临类似的问题
Answer 9:
对我来说,问题是,这是不相关的,我已经开发的模块单元测试并没有依赖于它的pom.xml我的模块。 在UT仍然认可我的模块,由于获取从共享的配置文件包列表。
当运行UT它没有编译新模块,因此它并不会产生ObjectFactory.java因此,我接收到错误,即使当我编译模块,我能够看到ObjectFactory.java
增加了以下依赖性:
<dependency>
<groupId>com.myCompany</groupId>
<artifactId>my-module-name</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
Answer 10:
我的解决办法是:
的JAXBContext上下文= JAXBContext.newInstance( 新类[] { “my.package.name”});
要么
的JAXBContext上下文= JAXBContext.newInstance( 新类[] {class.getName()});
要么
一个完整的解决方案:
public static <T> T deserializeFile(Class<T> _class, String _xml) {
try {
JAXBContext context = JAXBContext.newInstance(new Class[]{_class});
Unmarshaller um = context.createUnmarshaller();
File file = new File(_xml);
Object obj = um.unmarshal(file);
return _class.cast(obj);
} catch (JAXBException exc) {
return null;
}
}
工程100%
文章来源: Why can't JAXB find my jaxb.index when running inside Apache Felix?