3

I would like to make my OptaPlanner project run on the module path.

I created an example repository (mwkroening/optaplanner-modulepath-example) based on the cloud balancing demo in the docs.

The example project is running well on the classpath but there is an issue I can't workaround when trying to make it run on the module path. You can see the progress so far in PR #1.

The scoreDrl specified in the solverConfig.xml fails to load with the following exception:

Exception in thread "main" java.lang.IllegalArgumentException: The scoreDrl (io/github/mwkroening/optaplannermodulepathexample/cloudBalancingScoreRules.drl) does not exist as a classpath resource in the classLoader (jdk.internal.loader.ClassLoaders$AppClassLoader@7c16905e).
    at org.optaplanner.core@7.18.0.Final/org.optaplanner.core.config.score.director.ScoreDirectorFactoryConfig.buildDroolsScoreDirectorFactory(ScoreDirectorFactoryConfig.java:519)
    at org.optaplanner.core@7.18.0.Final/org.optaplanner.core.config.score.director.ScoreDirectorFactoryConfig.buildScoreDirectorFactory(ScoreDirectorFactoryConfig.java:351)
    at org.optaplanner.core@7.18.0.Final/org.optaplanner.core.config.solver.SolverConfig.buildSolver(SolverConfig.java:255)
    at org.optaplanner.core@7.18.0.Final/org.optaplanner.core.impl.solver.AbstractSolverFactory.buildSolver(AbstractSolverFactory.java:61)
    at io.github.mwkroening.optaplannermodulepathexample/io.github.mwkroening.optaplannermodulepathexample.App.main(App.java:14)

I got a similar exception before when calling SolverFactory.createFromXmlResource. My workaround for that problem was instead calling:

SolverFactory.createFromXmlInputStream(
  App.class.getResourceAsStream("cloudBalancingSolverConfig.xml"));

I looked at PLANNER-883 and psiroky/optaplanner-cloudbalancing-jdk9, but I think a classpath resource was used in that case and not one on the module path.

How could I resolve this issue? Perhaps I should open an issue instead of posting this here, right?

  • Very interesting experiment. See also my experiment with [running OptaPlanner on Graal](https://groups.google.com/forum/#!topic/optaplanner-dev/KXw-9GarGIk). – Geoffrey De Smet Mar 13 '19 at 09:59

1 Answers1

2

There's an overloaded method of every SolverFactory.createFrom*(...) that accepts a classloader: SolverFactory.createFrom*(..., classloader). That class loader isn't just used for loading the XML resources, but also the DRL resource.

So try:

SolverFactory.createFromXmlResource("/.../cloudBalancingSolverConfig.xml",
    App.class.getClassLoader())

I haven't tested this out yet myself, but if it works, I'd love to see this added to the "jigsaw" section in the manual (PR welcome :).

Geoffrey De Smet
  • 26,223
  • 11
  • 73
  • 120
  • Thanks for your answer! I had to open the package in `module-info.java` and add `--add-opens=java.base/java.lang=org.drools.core`. Supplying a class loader is not even necessary now. One thing that bothers me though, is that I can't find the module I have to open my package to. So now it's `opens [...];`, but I would really like something like `opens [...] to org.optaplanner.core;`. This way I would not be forced to open my package to everybody. I tried every module name, I could think of, but I didn't find the one. – Martin Kröning Mar 13 '19 at 14:11