![]() |
怕老婆的红茶 · 关于加强可再生能源建筑应用管理的通知-湖北省 ...· 4 月前 · |
![]() |
踢足球的镜子 · 深圳实验学校小学部地址|电话_深圳实验学校小 ...· 5 月前 · |
![]() |
风流倜傥的台灯 · 2024年全球56G ...· 5 月前 · |
![]() |
含蓄的闹钟 · 穿成一岁奶萌小团霸(一书成神)全本免费在线阅 ...· 7 月前 · |
![]() |
俊逸的肉夹馍 · 聚“光”成“链” ...· 12 月前 · |
它就在那里,在包中,它应该是索引的。不过,当我打电话给
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.inder.xml.bind.v2.ContextFactory创建默认上下文。在那里,异常被抛出(在
ContextFactor.createContext(String ClassLoader, Map)
内部),但我看不到发生了什么,因为源代码不在这里。
ETA
从ContentFactory的源代码来看,我发现了 here ,这可能是一段无法按预期工作的代码:
/**
* 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容器的类加载机制有关。不幸的是,我仍然有点超出我的能力范围。
编辑2:
我曾经在我的应用程序中遇到过类似的奇怪的类加载问题。如果我将其作为普通应用程序运行,一切正常,但当我将其作为Windows Service调用时,它开始出现ClassNotFoundExceptions故障。分析表明,线程以某种方式将其类加载器设置为空。我通过在线程上设置SystemClassLoader解决了这个问题:
// ...
thread.setContextClassLoader(ClassLoader.getSystemClassLoader());
thread.start();
// ...
我不知道你的容器是否允许这种改变。
好吧,这花了不少功夫,但答案并不那么令人惊讶,甚至也不是那么复杂:
JAXB找不到jaxb.index,因为默认情况下, JAXB 使用当前线程的类加载器(由 JAXB返回这在Felix中是行不通的,因为OSGi包和框架的线程有单独的类加载器。**
解决方案是从某个地方获得一个合适的类加载器,并使用
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无法找到包含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
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
希望这能对你有所帮助。
我刚刚遇到了这个问题。对我来说,解决方案是使用IBM的JRE而不是Oracle的,看起来JAXB实现对OSGI更友好。
对于相同的问题,我通过手动将包放入到导入中来解决它。
如果你在你的项目中使用maven,那么只需使用这个库:
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-osgi</artifactId>
<version>2.2.7</version>
</dependency>
它是为Glasfish服务器创建的,但也可以与Tomcat一起使用(选中)。有了这个库,您就可以轻松地将JAXB与OSGI包结合使用。
我成功地解决了这个问题,方法是将包含
ObjectFactory
的生成类的包添加到包定义的
<Private-Package>
部分,外加
org.jvnet.jaxb2_commons.*
我的解决方案是:
新上下文=JAXBContext.newInstance( JAXBContext Class[]{"my.package.name"} );
或
新上下文=JAXBContext.newInstance( JAXBContext Class[]{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;
![]() |
俊逸的肉夹馍 · 聚“光”成“链” 如此夺目-政务公开-青海省人民政府网 12 月前 |