为什么JAXB在Apache Felix中运行时找不到我的jaxb.in​​dex? [英] Why can't JAXB find my jaxb.index when running inside Apache Felix?

查看:136
本文介绍了为什么JAXB在Apache Felix中运行时找不到我的jaxb.in​​dex?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

它就在那里,在它应该索引的包中。仍然,当我打电话

It's right there, in the package that it should be indexing. Still, when I call

JAXBContext jc = JAXBContext.newInstance("my.package.name");

我得到一个JAXBException,说

I get a JAXBException saying that


my.package.name不包含ObjectFactory.class或jaxb.in​​dex

"my.package.name" doesnt contain ObjectFactory.class or jaxb.index

尽管它确实包含两个。

什么工作,但不是我想要的,是

What does work, but isn't quite what I want, is

JAXBContext jc = JAXBContext.newInstance(my.package.name.SomeClass.class);

来自其他人的这个问题出现在一些邮件列表和论坛上,但似乎无法得到答案。

This question from various other people appears on quite some mailing lists and forums but seemingly doesn't get answers.

我在OpenJDK 6上运行它,所以我得到了源包并将调试器放入库中。它首先查找jaxb.properties,然后查找系统属性并且无法找到,它尝试使用com.sun.internal.xml.bind.v2.ContextFactory创建默认上下文。在那里,Exception被抛出(在 ContextFactor.createContext(String ClassLoader,Map)里面),但我看不到发生了什么,因为源不在这里。

I'm running this on OpenJDK 6, so I got the source packages and stepped my debugger into the library. It starts by looking for jaxb.properties, then looks for system properties and failing to find either, it tries to create the default context using com.sun.internal.xml.bind.v2.ContextFactory. In there, the Exception gets thrown (inside ContextFactor.createContext(String ClassLoader, Map)), but I can't see what's going on because the source isn't here.

ETA

从ContentFactory的源代码判断,我发现< a href =http://www.java2s.com/Open-Source/Java-Document/6.0-JDK-Modules-com.sun/xml/com/sun/xml/internal/bind/v2/ContextFactory.java。 htm #createContextStringClassLoaderMapStringObjectrel =nofollow noreferrer>这里,这可能是无法正常工作的代码段:

Judging from the source code for ContentFactory, I found here, this is probably the piece of code that fails to work as intended:

/**
 * 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;
    }

来自我的 previous 体验,我猜这与运行的OSGi容器的类加载机制有关。不幸的是,我我仍然有点超出我的深度。

From my previous experience, I'm guessing that this has to do with the class loading mechanisms of the OSGi container that this is running in. Unfortunately, I am still a little out of my depth here.

推荐答案

好的,这需要一些挖掘,但答案并不令人惊讶甚至没那么复杂:

OK, this took quite some digging, but the answer is not that surprising and not even that complicated:

JAXB找不到jaxb.in​​dex,因为默认情况下, newInstance(String)使用当前线程的类加载器(由 Thread.getContextClassLoader()返回)。这在Felix中不起作用,因为OSGi包和框架的线程都有单独的类加载器。

JAXB can't find jaxb.index, because by default, newInstance(String) uses the current thread's class loader (as returned by Thread.getContextClassLoader()). This doesn't work inside Felix, because the OSGi bundles and the framework's threads have separate class loaders.

解决方案是从中获取合适的类加载器某处并使用 newInstance(String,ClassLoader)。我从包含 jaxb.in​​dex 的包中的一个类中得到了一个合适的类加载器,出于灵活性的原因,明智的选择可能是 ObjectFactory

The solution is to get a suitable class loader from somewhere and use newInstance(String, ClassLoader). I got a suitable class loader from one of the classes in the package that contains jaxb.index, a sensible choice for flexibility reasons probably is ObjectFactory:

ClassLoader cl = my.package.name.ObjectFactory.class.getClassLoader();
JAXBContext jc = JAXBContext.newInstance("my.package.name", cl);

也许你也可以在类加载器中获得 Bundle 实例正在使用,但我无法弄清楚如何,以上解决方案对我来说似乎是安全的。

Maybe you could also get at the class loader that the Bundle instance is using, but I couldn't figure out how, and the above solution seems safe to me.

这篇关于为什么JAXB在Apache Felix中运行时找不到我的jaxb.in​​dex?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆