i'm trying to use optaplanner OSGI-core. In a Java standard environment i have custimze the Vehiclerouting example in order to run it without UI and all works fine. After that i made an OSGI bundle of this project, but when it start i get this error from 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)
the exception is raised from this snippet of code:
@Override
protected Solver createSolver() {
File solver = new File(SOLVER_CONFIG);
SolverFactory solverFactory =SolverFactory.createFromXmlFile(solver);
return solverFactory.buildSolver();
}`
Googling i undestrand that it is a problem related to Xtream and Class Loading on OSGI, someone suggest to wrap Xstream inside the bundle that use it. But in my case Xstream metodhs are called by a 3rd part bundle (Optaplanner-core).
How can i fix this problem?
I think I solved this issue.
So, I have 3 bundles:
org.optaplanner.core.config.solver.SolverConfig
is
(Bundle B)SolverFactory.createFromXmlResource()
(Bundle C)Now, when Bundle B invokes 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).
However, in an OSGI environment, XStream lives in an isolated Classloader, so Bundle A can't access Bundle B's components. That said, to make XStream work, I have to call the Xstream.setClassloader(getclass().getClassloader())
after the initialization.
Finally, XStream must resolve the class that I declare into the solver.xml and this class is in Bundle C. But since OptaPlanner-Core, obviously, can't import that class, I need to add <DynamicImport-Package>*</DynamicImport-Package>
in Bundle B's pom.xml. In this way OptaPlanner can load everything it needs at runtime.