首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Dozer: Osgi环境中的ClassNotFoundException

Dozer: Osgi环境中的ClassNotFoundException
EN

Stack Overflow用户
提问于 2014-05-07 23:30:17
回答 3查看 3.1K关注 0票数 0

我在Osgi环境中使用Dozer (Apache karaf)。版本user 5.4.0。Pom依赖如下所示。

代码语言:javascript
复制
    <dependency>
        <groupId>net.sf.dozer</groupId>
        <artifactId>dozer-osgi</artifactId>
        <version>5.4.0</version>
    </dependency>

我们通过xml文件使用自定义映射。当dozer mapper引用映射的映射xml时,它不会获取文件中引用的类。我得到了以下异常。

代码语言:javascript
复制
2014-05-07 00:12:13,734[qtp1876495841-122]|ERROR|com.ge.alsp.dspkservice.services.impl.UserServiceImpl|354-alsp-service-2.0.0|Failed to get user profile.
org.dozer.MappingException: java.lang.ClassNotFoundException: com.ge.alsp.model.usermanagement.Timezone not found from bundle [dsp.core]
    at org.dozer.util.MappingUtils.throwMappingException(MappingUtils.java:82)
    at org.dozer.util.DefaultClassLoader.loadClass(DefaultClassLoader.java:38)
    at org.dozer.util.MappingUtils.loadClass(MappingUtils.java:224)
    at org.dozer.loader.DozerBuilder$MappingBuilder.classA(DozerBuilder.java:129)
    at org.dozer.loader.xml.XMLParser.parseMapping(XMLParser.java:188)
    at org.dozer.loader.xml.XMLParser.read(XMLParser.java:135)
    at org.dozer.loader.xml.XMLParser.read(XMLParser.java:43)
    at org.dozer.loader.xml.MappingStreamReader.read(MappingStreamReader.java:51)
    at org.dozer.loader.xml.MappingFileReader.read(MappingFileReader.java:58)
    at org.dozer.DozerBeanMapper.loadFromFiles(DozerBeanMapper.java:227)

你知道如何让推土机在osgi中工作吗?

EN

回答 3

Stack Overflow用户

发布于 2014-06-02 20:53:06

Dozer使用类加载器来加载至少以下资源:

  • 映射定义XML文件。映射定义文件包含自定义映射规则。使用Class.forName().

基于完全限定类名的

Dozer有一个可插拔的类加载配置,它允许为类和资源设置自定义的类加载器:

代码语言:javascript
复制
org.dozer.util.DozerClassLoader classLoader=...;
BeanContainer.getInstance().setClassLoader(classLoader);  

然而,推土机在设计时并没有考虑到OSGi。自定义类加载器设置在一个推土器单例上。再加上映射定义文件的延迟加载,可能会产生意想不到的结果。

因为类加载器设置在单例上,所以它会影响通过Dozer导入资源的所有包。但是,如果以下条件有效,则可以实施可接受的解决方法:

在捆绑包的启动阶段完全设置

  • 捆绑包。

第一个条件将防止BeanContainer的类加载器属性在包启动之前被覆盖。

第二个条件将允许Dozer在BeanContainer单例被另一个捆绑包重置之前加载任何自定义映射文件和其中引用的所有类。

唯一缺少的部分是定制的Dozer类加载器,以及捆绑包中的Dozer初始化。

委托给包的类加载器的Dozer类加载器如下所示:

代码语言:javascript
复制
public class OsgiDozerClassLoader implements DozerClassLoader {
private BundleContext context;

@Override
public Class<?> loadClass(String className) {
    try {
        return context.getBundle().loadClass(className);
    } catch (ClassNotFoundException e) {
        return null;
    }
}

@Override
public URL loadResource(String uri) {
    URL url;

    url = context.getBundle().getResource(uri);

    if (url == null) {
        url = DozerClassLoader.class.getClassLoader().getResource(uri);
    }

    return url;
}

public void setContext(BundleContext context) {
    this.context = context;
}
}

然后在捆绑包启动期间-例如,在蓝图中急切地创建bean构造器或init-method -设置自定义类加载器、映射文件并强制解析映射文件:

代码语言:javascript
复制
public DozerBeanMapper getMapper(List<String> files) {
    BeanContainer.getInstance().setClassLoader(classLoader);

    DozerBeanMapper mapper = new DozerBeanMapper();
    mapper.setMappingFiles(files);

    // Force loading of the dozer.xml now instead of loading it
    // upon the first mapping call
    mapper.getMappingMetadata();

    return mapper;
}

上面的方法不是最优的。在实践中,它似乎是可行的,而且是一个可行的变通方法,直到单例被移除&类加载在Dozer中变得更加OSGi友好。

这个答案改编自我的博客:http://modio.io/dozer-pojo-mapper-in-osgi/

票数 2
EN

Stack Overflow用户

发布于 2014-05-09 14:45:33

看起来您需要将相应的包导入到"dsp.core“包中。只要不导入这个包,推土机就不能访问它。

票数 0
EN

Stack Overflow用户

发布于 2014-05-12 13:44:55

您能确定在Apache Karaf中dozer bundle是否处于活动状态吗?您可以通过can控制台或命令查看。

我在OSGI (Apache Karaf )中使用以下工件,并为我工作

代码语言:javascript
复制
    <dependency>
        <groupId>net.sf.dozer</groupId>
        <artifactId>dozer</artifactId>
        <version>5.4.0</version>
    </dependency>
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/23522072

复制
相关文章

相似问题

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