Xstream - OSGI - OptaPlanner

Xstream - OSGI - OptaPlanner

我正在尝试使用 optaplanner OSGI-core。 在 Java 标准环境中,我已经自定义了 Vehiclerouting 示例,以便 运行 它没有 UI 并且一切正常。之后我制作了这个项目的 OSGI 包,但是当它启动时我从 Xstream.

得到这个错误
com.thoughtworks.xstream.mapper.CannotResolveClassException: org.optaplanner.core.config.solver.SolverConfig
at com.thoughtworks.xstream.mapper.DefaultMapper.realClass(DefaultMapper.java:79)
at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:30)
at com.thoughtworks.xstream.mapper.DynamicProxyMapper.realClass(DynamicProxyMapper.java:55)
at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:30)
at com.thoughtworks.xstream.mapper.PackageAliasingMapper.realClass(PackageAliasingMapper.java:88)
at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:30)
at com.thoughtworks.xstream.mapper.ClassAliasingMapper.realClass(ClassAliasingMapper.java:79)
at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:30)
at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:30)
at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:30)
at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:30)
at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:30)
at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:30)
at com.thoughtworks.xstream.mapper.ArrayMapper.realClass(ArrayMapper.java:74)
at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:30)
at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:30)

此代码片段引发异常:

     @Override
    protected Solver createSolver() {
       File solver = new File(SOLVER_CONFIG);
       SolverFactory solverFactory =SolverFactory.createFromXmlFile(solver);

       return solverFactory.buildSolver();
}`

谷歌搜索我不明白这是一个与 Xtream 和 Class 在 OSGI 上加载相关的问题,有人建议将 Xstream 包装在使用它的包中。但在我的例子中,Xstream 方法由第三部分包(Optaplanner-core)调用。

我该如何解决这个问题?

我想我解决了这个问题。

所以,我有 3 个捆绑包:

  • XStream (捆绑包 A)
  • OptaPlanner-Core,也就是org.optaplanner.core.config.solver.SolverConfig所在的位置 (B 组)
  • 我的代码使用 SolverFactory.createFromXmlResource() (Bundle C)

现在,当 Bundle B 调用 xStream.fromXML (https://github.com/droolsjbpm/optaplanner/blob/2a0c40283c8b8a068d24c40297581ff2c597bf1e/optaplanner-core/src/main/java/org/optaplanner/core/impl/solver/XStreamXmlSolverFactory.java#L117) it needs to resolve SolverConfig.class (https://github.com/droolsjbpm/optaplanner/blob/master/optaplanner-core/src/main/java/org/optaplanner/core/impl/solver/XStreamXmlSolverFactory.java#L51) 时。

然而,在 OSGI 环境中,XStream 存在于一个孤立的类加载器中,因此 Bundle A 无法访问 Bundle B 的组件。也就是说,要使 XStream 工作,我必须在初始化后调用 Xstream.setClassloader(getclass().getClassloader())

最后,XStream 必须将我声明的 class 解析为 solver.xml 并且这个 class 在 Bundle C 中。但是由于 OptaPlanner-Core,显然,无法导入 class,我需要在 Bundle B 的 pom.xml 中添加 <DynamicImport-Package>*</DynamicImport-Package>。通过这种方式,OptaPlanner 可以在运行时加载它需要的一切。