[jboss-jira] [JBoss JIRA] (DROOLS-1071) NPE's stacktracke for an MvelConstraint.evaluate() should give a line number from the source DRL file
Geoffrey De Smet (JIRA)
issues at jboss.org
Fri Feb 26 11:45:01 EST 2016
[ https://issues.jboss.org/browse/DROOLS-1071?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
Geoffrey De Smet moved PLANNER-541 to DROOLS-1071:
--------------------------------------------------
Project: Drools (was: OptaPlanner)
Key: DROOLS-1071 (was: PLANNER-541)
Issue Type: Enhancement (was: Bug)
Workflow: GIT Pull Request workflow (was: classic default workflow)
Component/s: core engine
(was: optaplanner-core)
Steps to Reproduce: (was: DRL:
{code:java}
package com.rdthree.plenty.services.activities.planner;
dialect "java"
import org.optaplanner.core.api.score.buildin.simple.SimpleScoreHolder;
import org.optaplanner.core.api.score.buildin.hardsoft.HardSoftScoreHolder;
import org.joda.time.Interval;
import org.joda.time.DateTime;
import org.apache.commons.lang.time.DateUtils;
import org.optaplanner.core.api.domain.solution.PlanningEntityCollectionProperty;
import org.optaplanner.core.api.domain.solution.PlanningSolution;
import org.optaplanner.core.api.domain.solution.Solution;
import org.optaplanner.core.api.domain.valuerange.ValueRangeProvider;
import org.optaplanner.core.api.score.buildin.hardsoft.HardSoftScore;
import com.rdthree.plenty.config.GeneralPrefs;
import com.rdthree.plenty.services.activities.helpers.dtos.TaskPlannerDto;
import com.rdthree.plenty.services.activities.helpers.dtos.TaskResourceAllocationPlannerDto;
import com.rdthree.plenty.services.activities.helpers.dtos.SkillsAndRatesPlannerDto;
import com.rdthree.plenty.services.activities.helpers.dtos.EquipmentEquipmentTypesPlannerDto;
import com.rdthree.plenty.services.activities.helpers.dtos.ProductPlannerDto;
import com.rdthree.plenty.services.activities.helpers.dtos.LabourDayOffPlannerDto;
import com.rdthree.plenty.services.activities.helpers.dtos.OnHandForProduct;
import com.rdthree.plenty.services.activities.planner.TaskRequirementsMapper;
import com.rdthree.plenty.domain.users.LabourDayOff.ApprovalState;
import com.rdthree.plenty.services.activities.planner.ScheduleState;
global HardSoftScoreHolder scoreHolder;
dialect "java"
dialect "mvel"
// ############################################################################
// Soft constraints
// ############################################################################
// DOC
rule "setAllConflictingToFalseFirst"
salience 100
when
$allocation : TaskResourceAllocationPlannerDto()
then
$allocation.setScheduleState(ScheduleState.SCHEDULING);
$allocation.setLabourDayOffConflict(null);
$allocation.setProductShortage(0);
end
rule "taskDateChangeRule"
when
TaskPlannerDto($taskId : id, $taskStart : interval.getStart().toDate())
TaskRequirementsMapper( taskId == $taskId, $taskReqStartMS : startDate.getTime(), startDate.getTime() != $taskStart.getTime())
then
scoreHolder.addSoftConstraintMatch(kcontext, Math.round(Math.abs($taskReqStartMS - $taskStart.getTime()) / 1000 / 60 / 60) * -100);
end
rule "taskPlanIndexChangeRule"
when
$task1 : TaskPlannerDto($task1Activity : activity, $task1Plan : activity.getPlan(), $task1Start : interval.getStart().toDate())
TaskPlannerDto(!activity.equals($task1Activity), activity.getPlan().equals($task1Plan), $task1Activity.indexInPlan > activity.indexInPlan, interval.getStart().toDate() < $task1Start)
TaskPlannerDto(!activity.equals($task1Activity), activity.getPlan().equals($task1Plan), $task1Activity.indexInPlan < activity.indexInPlan, interval.getStart().toDate() < $task1Start)
then
scoreHolder.addHardConstraintMatch(kcontext, -100000);
end
rule "taskLengthChangeRule"
when
TaskPlannerDto($taskId : id, $taskLength : interval.toPeriod().getDays())
TaskRequirementsMapper( taskId == $taskId, $taskReqLength : length, length!=$taskLength)
then
scoreHolder.addSoftConstraintMatch(kcontext, Math.abs($taskReqLength - $taskLength) * -1000);
end
rule "taskResourceChangeRule"
when
$allocation : TaskResourceAllocationPlannerDto( $taskId : taskId )
$mapper : TaskRequirementsMapper( taskId == $taskId )
TaskRequirement( resourceClass.equals($allocation.getResourceClass()), resourceTypeOrSkill.getId() == $allocation.getResourceTypeId(), originalResource.getId() != $allocation.getResource().getId()) from $mapper.getRequirements()
then
scoreHolder.addSoftConstraintMatch(kcontext, -10);
end
// This rule checks if the allocated resource has already been allocated to the same task
rule "duplicateResourceAllocation"
when
TaskPlannerDto($taskId : id)
TaskResourceAllocationPlannerDto($alloc1Id : id, taskId == $taskId, $alloc1Resource : resource)
TaskResourceAllocationPlannerDto(id != $alloc1Id, taskId == $taskId, resource.getId() == $alloc1Resource.getId())
then
scoreHolder.addHardConstraintMatch(kcontext, -100000);
end
// This rule creates a constraint based on overlap of two tasks which use the
// same labourer at the same time. The constraint is multipled by the size of the overlap in days
rule "TaskLabourerTimeOverlap"
when
$task1 : TaskPlannerDto($task1Interval : interval)
$task1ResourceAllocation : TaskResourceAllocationPlannerDto(taskId == $task1.id, resource instanceof SkillsAndRatesPlannerDto, $task1UserId : resource.getUserId())
$task2 : TaskPlannerDto($task1.id != id, $task1Interval.overlaps(interval))
$task2ResourceAllocation : TaskResourceAllocationPlannerDto(taskId == $task2.id, resource instanceof SkillsAndRatesPlannerDto, resource.getUserId().equals($task1UserId))
then
scoreHolder.addHardConstraintMatch(kcontext, $task1Interval.overlap($task2.getInterval()).toPeriod(org.joda.time.PeriodType.days()).getDays() * -1);
$task1ResourceAllocation.setScheduleState(ScheduleState.CONFLICT);
$task2ResourceAllocation.setScheduleState(ScheduleState.CONFLICT);
$task1.setState(ScheduleState.CONFLICT);
$task2.setState(ScheduleState.CONFLICT);
end
// This rule creates a constraint based on overlap of a task and it's labour days off
// The constraint is multipled by the size of the overlap in days
rule "TaskLabourerDayOffOverlap"
when
$task1 : TaskPlannerDto($taskInterval : interval)
$task1ResourceAllocation : TaskResourceAllocationPlannerDto(taskId == $task1.id, resource instanceof SkillsAndRatesPlannerDto, $task1UserId : resource.getUserId())
$labourDayOff : LabourDayOffPlannerDto(userId == $task1UserId, $taskInterval.contains(new DateTime(date).plusMinutes(15)), state.equals(ApprovalState.APPROVED))
then
scoreHolder.addHardConstraintMatch(kcontext, -1);
$task1ResourceAllocation.setScheduleState(ScheduleState.CONFLICT);
$task1ResourceAllocation.setLabourDayOffConflict($labourDayOff.getDate().toDate());
$task1.setState(ScheduleState.CONFLICT);
end
// This rule creates a constraint based on overlap of two tasks which use the
// same equipment at the same time. The constraint is multipled by the size of the overlap in days
rule "TaskEquipmentTimeOverlap"
when
$task1 : TaskPlannerDto($task1Interval : interval)
$task1ResourceAllocation : TaskResourceAllocationPlannerDto(taskId == $task1.id, resource instanceof EquipmentEquipmentTypesPlannerDto, $task1EquipmentId : resource.getEquipmentId())
$task2 : TaskPlannerDto($task1.id != id, $task1Interval.overlaps(interval))
$task2ResourceAllocation : TaskResourceAllocationPlannerDto(taskId == $task2.id, resource instanceof EquipmentEquipmentTypesPlannerDto, resource.getEquipmentId() == $task1EquipmentId)
then
scoreHolder.addHardConstraintMatch(kcontext, $task1Interval.overlap($task2.getInterval()).toPeriod(org.joda.time.PeriodType.days()).getDays() * -1);
$task1ResourceAllocation.setScheduleState(ScheduleState.CONFLICT);
$task2ResourceAllocation.setScheduleState(ScheduleState.CONFLICT);
$task1.setState(ScheduleState.CONFLICT);
$task2.setState(ScheduleState.CONFLICT);
end
// This rule create a constraint based on product defficiency for a product at a taks's start date
rule "TaskProductShortage"
when
$task : TaskPlannerDto( $taskId : id, $taskNeedsProductBy : interval.getStart().plusDays(0).withTimeAtStartOfDay())
$allocation : TaskResourceAllocationPlannerDto( taskId == $taskId, resource instanceof ProductPlannerDto)
OnHandForProduct(date.compareTo($taskNeedsProductBy) == 0 , productId == $allocation.resource.getId(), $onHandAmount : amount, amount - $allocation.amount <= 0)
then
scoreHolder.addHardConstraintMatch(kcontext, $allocation.getAmount() * -1);
$allocation.setScheduleState(ScheduleState.CONFLICT);
$allocation.setProductShortage($allocation.getAmount());
$task.setState(ScheduleState.CONFLICT);
end
{code}
added domain classes as attachments
)
Affects Version/s: 6.4.0.Beta2
6.3.0.Final
(was: 6.3.0.Final)
(was: 6.4.0.Beta2)
> NPE's stacktracke for an MvelConstraint.evaluate() should give a line number from the source DRL file
> -----------------------------------------------------------------------------------------------------
>
> Key: DROOLS-1071
> URL: https://issues.jboss.org/browse/DROOLS-1071
> Project: Drools
> Issue Type: Enhancement
> Components: core engine
> Affects Versions: 6.4.0.Beta2, 6.3.0.Final
> Environment: JDK: Java 7
> OS: Mac OSX 10.10.2
> IDE: Spring Tool Suite 3.6.4
> Reporter: Ido Flax
> Assignee: Geoffrey De Smet
> Attachments: AbstractPlannerDto.java, activity-scoring.drl, EquipmentEquipmentTypesPlannerDto.java, LabourDayOffPlannerDto.java, OnHandForProduct.java, ProductInventoryTransactionPlannerDto.java, ProductPlannerDto.java, SkillsAndRatesPlannerDto.java, TaskPlannerDto.java, TaskResourceAllocationPlannerDto.java, TaskResourcePlannerDto.java, UserPlannerDto.java
>
>
> The attached code generates an NPE when running optaplanner/drools, but that stacktrace doesn't tell me which DRL line is responsible for it.
> Stacktrace:
> {code:java}
> Caused by: java.lang.NullPointerException: null
> at ConditionEvaluatoreaa3997683d949e28ce6eaf6feca0ced.evaluate(Unknown Source) <================ No source DRL line
> at org.drools.core.rule.constraint.MvelConstraint.evaluate(MvelConstraint.java:258)
> at org.drools.core.rule.constraint.MvelConstraint.isAllowedCachedLeft(MvelConstraint.java:226)
> at org.drools.core.common.DoubleBetaConstraints.isAllowedCachedLeft(DoubleBetaConstraints.java:111)
> at org.drools.core.phreak.PhreakJoinNode.doLeftInserts(PhreakJoinNode.java:112)
> at org.drools.core.phreak.PhreakJoinNode.doNode(PhreakJoinNode.java:75)
> at org.drools.core.phreak.RuleNetworkEvaluator.switchOnDoBetaNode(RuleNetworkEvaluator.java:547)
> at org.drools.core.phreak.RuleNetworkEvaluator.evalBetaNode(RuleNetworkEvaluator.java:533)
> at org.drools.core.phreak.RuleNetworkEvaluator.evalNode(RuleNetworkEvaluator.java:369)
> at org.drools.core.phreak.RuleNetworkEvaluator.innerEval(RuleNetworkEvaluator.java:329)
> at org.drools.core.phreak.RuleNetworkEvaluator.outerEval(RuleNetworkEvaluator.java:163)
> at org.drools.core.phreak.RuleNetworkEvaluator.evaluateNetwork(RuleNetworkEvaluator.java:120)
> at org.drools.core.phreak.RuleExecutor.reEvaluateNetwork(RuleExecutor.java:194)
> at org.drools.core.phreak.RuleExecutor.evaluateNetworkAndFire(RuleExecutor.java:73)
> at org.drools.core.common.DefaultAgenda.fireNextItem(DefaultAgenda.java:1003)
> at org.drools.core.common.DefaultAgenda.fireLoop(DefaultAgenda.java:1346)
> at org.drools.core.common.DefaultAgenda.fireAllRules(DefaultAgenda.java:1284)
> at org.drools.core.impl.StatefulKnowledgeSessionImpl.internalFireAllRules(StatefulKnowledgeSessionImpl.java:1303)
> at org.drools.core.impl.StatefulKnowledgeSessionImpl.fireAllRules(StatefulKnowledgeSessionImpl.java:1293)
> at org.drools.core.impl.StatefulKnowledgeSessionImpl.fireAllRules(StatefulKnowledgeSessionImpl.java:1274)
> at org.optaplanner.core.impl.score.director.drools.DroolsScoreDirector.calculateScore(DroolsScoreDirector.java:84)
> at org.optaplanner.core.impl.solver.recaller.BestSolutionRecaller.solvingStarted(BestSolutionRecaller.java:70)
> at org.optaplanner.core.impl.solver.DefaultSolver.solvingStarted(DefaultSolver.java:197)
> at org.optaplanner.core.impl.solver.DefaultSolver.solve(DefaultSolver.java:175)
> {code}
--
This message was sent by Atlassian JIRA
(v6.4.11#64026)
More information about the jboss-jira
mailing list