16.4. Other Environments

16.4.1. JBoss Modules, WildFly and JBoss EAP

To deploy a Planner web application on WildFly, simply include the optaplanner dependency JARs in the WAR file’s WEB-INF/lib directory (just like any other dependency) as shown in the optaplanner-webexamples-*.war. However, in this approach the WAR file can easily grow to several MB in size, which is fine for a one-time deployment, but too heavyweight for frequent redeployments (especially over a slow network connection).

The remedy is to deliver the optaplanner JARs in a JBoss module to WildFly and create a skinny WAR. Let’s create a module called org.optaplanner:

  1. Navigate to the directory ${WILDFLY_HOME}/modules/system/layers/base/. This directory contains the JBoss modules of WildFly. Create directory structure org/optaplanner/main for our new module.

    1. Copy optaplanner-core-${version}.jar and all its direct and transitive dependency JARs into that new directory. Use the mvn dependency:tree command on each optaplanner artifact to discover all dependencies.
    2. Create the file module.xml in that new directory. Give it this content:

      <?xml version="1.0" encoding="UTF-8"?>
      <module xmlns="urn:jboss:module:1.3" name="org.optaplanner">
        <resources>
          ...
          <resource-root path="kie-api-${version}.jar"/>
          ...
          <resource-root path="optaplanner-core-${version}.jar"/>
          ...
          <resource-root path="."/>
        </resources>
        <dependencies>
          <module name="javaee.api"/>
        </dependencies>
      </module>
  2. Navigate to the deployed WAR file.

    1. Remove optaplanner-core-${version}.jar and all its direct and transitive dependency JARs from the WEB-INF/lib directory in the WAR file.
    2. Create the file jboss-deployment-structure.xml in the WEB-INF/lib directory. Give it this content:

      <?xml version="1.0" encoding="UTF-8" ?>
      <jboss-deployment-structure>
         <deployment>
            <dependencies>
               <module name="org.optaplanner" export="true"/>
            </dependencies>
         </deployment>
      </jboss-deployment-structure>

Because of JBoss Modules' ClassLoader magic, you’ll likely need to provide the ClassLoader of your classes during the SolverFactory creation, so it can find the classpath resources (such as the solver config, score DRL’s and domain classes) in your JARs.

16.4.2. OSGi

The optaplanner-core JAR includes OSGi metadata in its MANIFEST.MF file to function properly in an OSGi environment too. Furthermore, the Maven artifact drools-karaf-features (which will be renamed to kie-karaf-features) contains a features.xml file that supports the OSGi-feature optaplanner-engine.

Because of the OSGi’s ClassLoader magic, you’ll likely need to provide the ClassLoader of your classes during the SolverFactory creation, so it can find the classpath resources (such as the solver config, score DRLs and domain classes) in your JARs.

Note

Planner does not require OSGi. It works perfectly fine in a normal Java environment too.

16.4.3. Android

Android is not a complete JVM (because some JDK libraries are missing), but Planner works on Android with easy Java or incremental Java score calculation. The Drools rule engine does not work on Android yet, so Drools score calculation doesn’t work on Android and its dependencies need to be excluded.

Workaround to use Planner on Android:

  1. Add a dependency to the build.gradle file in your Android project to exclude org.drools and xmlpull dependencies:

    dependencies {
        ...
        compile('org.optaplanner:optaplanner-core:...') {
            exclude group: 'xmlpull'
            exclude group: 'org.drools'
        }
        ...
    }