为什么不能修订找到我的修订。指数时内运行的阿帕奇菲利克斯?
-
20-08-2019 - |
题
它就在那里,在包,这应该是编制索引。然而,当我电话
JAXBContext jc = JAXBContext.newInstance("my.package.name");
我得到一个JAXBException说
"我的。包。名字"不包含ObjectFactory.class 或修订。索引
虽然它包含两个。
什么工作,但并不是我想要的是
JAXBContext jc = JAXBContext.newInstance(my.package.name.SomeClass.class);
这个问题从其他各种人出现在相当长的一邮件列表和论坛,但似乎没有得到答复。
我在6们可根据最新的技术提供一些,所以我来源的软件包,并加强我的调试进入图书馆。它开始通过寻找修订。特性,然后查找系统的性质和未能找到任,它试图创建的默认方面使用com.太阳。内部。xml。绑定。v2。ContextFactory.在那里,该例外会引发(内部 ContextFactor.createContext(String ClassLoader, Map)
的),但是我看不到什么因为源不是这里。
ETA:
从源代码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;
}
解决方案
好吧,这把相当一些挖掘,但答案不是那令人惊讶的和不复杂:
修订不能找到修订。索引的,因为默认情况下, newInstance(String)
使用当前的线的舱装载机(如返回的 Thread.getContextClassLoader()
).这不起作用的内部费利克斯,因为访束和框架的线有单独的类装载机。
该方案是获得一个合适的类装载机从什么地方和使用 newInstance(String, ClassLoader)
.我得到一个合适的类装载程序中的一个类包含 jaxb.index
, ,一个明智的选择灵活性的原因可能是 ObjectFactory
:
ClassLoader cl = my.package.name.ObjectFactory.class.getClassLoader();
JAXBContext jc = JAXBContext.newInstance("my.package.name", cl);
也许你也可以获得在这类装载机, Bundle
实例是使用,但我想不出如何,上述解决方案似乎是安全的我。
其他提示
我也面临类似问题的项目我的工作。在阅读 http://jaxb.java.net/faq/index.html#classloader 我意识到,JAXBContext是没能找到包含修订。索引。
我会尽量让这尽可能明确。
我们
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
涉及到 修订. B类是JAXBContext和bMethod是newInstance()
如果你熟悉访包限制,那么它必须非常清楚,现在, 束B 是不是进口包 com.c i。e C类 是 不可见的 要 B类 因此,它不能C.实例
该方案将通过一个 类加载 到bMethod.这类装入器应该来自一个 捆绑,这就是进口com.c.在这种情况下,我们可以通过 A.类。getClassLoader() 由于 捆绑在一是进口com.c
希望这是有益的。
出于同样的问题,我解决它通过手动把包放到进口。
如果您使用的是专家在您的项目,然后只是用这个图书馆:
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-osgi</artifactId>
<version>2.2.7</version>
</dependency>
它的创建Glasfish服务器,但是也正在与Tomcat(检查).与此库伊斯利你可以使用的修订与访束。
编辑2:
我曾经有类似奇怪的类装问题在我的应用程序。如果我运行了它作为一个正常的应用程序,一切都是好的但当我援引它作为一个窗口服务,它开始失败ClassNotFoundExceptions.该分析表明该线有各类装入器作为空。我解决了这个问题通过设置SystemClassLoader在线程:
// ...
thread.setContextClassLoader(ClassLoader.getSystemClassLoader());
thread.start();
// ...
不知道,如果你容许这种变化。
我刚刚碰到这个问题。对我来说,解决办法是使用IBM的java运行环境,而不是甲骨文。似乎是修订执行更多的访友好的在那一个。
我成功地解决这一添加的包我的生课程含有 ObjectFactory
来的 <Private-Package>
部分的我捆绑的定义,再加上 org.jvnet.jaxb2_commons.*
有可能是另一种情况下,可以给这个问题。
当你安装和开始束其出口的软件包,其中包含的修订。指数或objectFactory.java
然后请确保束进口的课程被停止或指向正确的包名。
也检查出口和进口发言pom.xml
面临类似的问题在servicemix(-卡拉夫)访容器
我的问题是,一个单元的测试,它是不相关的模块,我已经开发出未曾依赖在这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>
我的解决方案是:
JAXBContext上下文=JAXBContext.newInstance(新类[]{"我的。包。名为"});
或
JAXBContext上下文=JAXBContext.newInstance(新类[]{类。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%