首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >为什么JAXB在Apache Felix中运行时找不到我的jaxb.index?

为什么JAXB在Apache Felix中运行时找不到我的jaxb.index?
EN

Stack Overflow用户
提问于 2009-06-25 10:21:51
回答 10查看 55.4K关注 0票数 54

它就在那里,在包中,它应该是索引的。不过,当我打电话给

代码语言:javascript
复制
JAXBContext jc = JAXBContext.newInstance("my.package.name");

我收到一个JAXBException说

"my.package.name“不包含ObjectFactory.class或jaxb.index

尽管它确实包含了这两个。

有效的,但不完全是我想要的,是

代码语言:javascript
复制
JAXBContext jc = JAXBContext.newInstance(my.package.name.SomeClass.class);

这个来自不同人的问题出现在相当多的邮件列表和论坛上,但似乎没有得到答案。

我在OpenJDK 6上运行这个程序,所以我获得了源码包并将我的调试器单步调试到库中。它首先查找jaxb.properties,然后查找系统属性,但两者都找不到,它尝试使用com.sun.inder.xml.bind.v2.ContextFactory创建默认上下文。在那里,异常被抛出(在ContextFactor.createContext(String ClassLoader, Map)内部),但我看不到发生了什么,因为源代码不在这里。

ETA

从ContentFactory的源代码来看,我发现了here,这可能是一段无法按预期工作的代码:

代码语言:javascript
复制
/**
 * 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 experience中,我猜测这与运行它的OSGi容器的类加载机制有关。不幸的是,我仍然有点超出我的能力范围。

EN

回答 10

Stack Overflow用户

回答已采纳

发布于 2009-06-25 13:08:30

好吧,这花了不少功夫,但答案并不那么令人惊讶,甚至也不是那么复杂:

JAXB找不到jaxb.index,因为默认情况下, JAXB使用当前线程的类加载器(由JAXB返回这在Felix中是行不通的,因为OSGi包和框架的线程有单独的类加载器。**

解决方案是从某个地方获得一个合适的类加载器,并使用newInstance(String, ClassLoader)。我从包含jaxb.index的包中的一个类中获得了一个合适的类加载器,出于灵活性的考虑,明智的选择可能是ObjectFactory

代码语言:javascript
复制
ClassLoader cl = my.package.name.ObjectFactory.class.getClassLoader();
JAXBContext jc = JAXBContext.newInstance("my.package.name", cl);

也许您还可以使用Bundle实例正在使用的类加载器,但我不知道如何使用,上面的解决方案对我来说似乎是安全的。

票数 63
EN

Stack Overflow用户

发布于 2011-10-01 01:41:39

我在我正在做的项目中遇到了类似的问题。在阅读了http://jaxb.java.net/faq/index.html#classloader之后,我意识到JAXBContext无法找到包含jaxb.index的包。

我会尽量把这一点说清楚。

我们有

代码语言:javascript
复制
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 is not visible to 类B,因此它不能实例化C。

解决方案是将ClassLoader传递给bMethod。此ClassLoader应该来自正在导入com.c的包。在本例中,我们可以传递A.class.getClassLoader(),因为包A正在导入com.c

希望这能对你有所帮助。

票数 6
EN

Stack Overflow用户

发布于 2013-01-21 12:22:46

对于相同的问题,我通过手动将包放入到导入中来解决它。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1043109

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档