Search code examples
droolskiemoqui

KIE component in moqui, getting error Unable to resolve ObjectType


I've used KIE component and drools rule to create calculating-rule of shipping products. I defined my rule in *.drl as following:

My *.drl file:

package shipment.orderrate;
dialect "mvel"
import org.mag.erp.model.Product
function Double calculateVolume(Double height, Double width, Double depth){
    if(height == null || width == null || depth == null){
        return 0d;
    }
    if(height == -1 || width == -1 || depth == -1){
        return 0d;
    }
    return height * width * depth;
}

rule "Calculate Shipping_by_volumne"
when
    $p: Product(calculateVolume(height, width, depth) >= 0.0, calculateVolume(height, width, depth) < 100.0, shippingTotal == null
then
    modify($p){
        setShippingTotal(80000.0)
    };
end

The java file class Product.java is located in my component with source code:

package org.mag.erp.model;

import java.io.Serializable;

public class Product implements Serializable {
    private String productId;
    private Double height;
    private Double width;
    private Double weight;
    private Double depth;
    private Double shippingTotal;

    //*getter and setter property*
} 

When I started moqui, it giving me this error:

00:06:57.151 ERROR         main            o.drools.c.k.b.i.KieProject Unable to build KieBaseModel:MagOrderShippingRateKB
Unable to resolve ObjectType 'Product' : [Rule name='Calculate Shipping_by_volumne']

Unable to Analyse Expression @Modify with($p){        setShippingTotal(80000.0)    };:
[Error: unable to resolve method using strict-mode: org.drools.core.spi.KnowledgeHelper.$p()]

But if I move Product.java file to org.moqui.util package in moqui-util component and edit import org.mag.erp.model.Product to import org.moqui.util.Product in my *.drl file, moqui will start normally and have no error.

Why this happen? What is the special config in moqui-util that make KieBase build with no error when I put Product.java into this component?


Solution

  • This looks like a ClassLoader issue. In order to support runtime additions to the classpath Moqui uses a custom ClassLoader that supports this behavior, including the 'classes' and 'lib' directories under the 'runtime' directory or in component directories. The custom ClassLoader (MClassLoader) is set as the context ClassLoader for each thread within the servlet container or threads created internally for Moqui background jobs, etc.

    The most likely reason this happens with KIE 'mvel' scripts is that it does not use the current thread's context ClassLoader (ie the mvel compiler isn't using it) or it is running in a thread not initialized through Moqui Framework so the thread's context ClassLoader is not set yet.

    The first step to fix this would be to research classloading options for the mvel compiler. There may be a file where it is configured but it is more likely an API option that is needed, perhaps to specify the ClassLoader explicitly so it uses the thread's context ClassLoader. If you want help pursuing that it isn't really a question any more and doesn't belong on StackOverflow. The Moqui community collaboration resources available are described on the Moqui web site here:

    https://www.moqui.org/m/docs/moqui/Community+Guide