1

I'm facing a problem using Spring with Drools. My main problem is that in the unit tests do not occur the error. Follows below the exception

java.lang.RuntimeException: Unexpected global [premioService]

This error occurs when I try to set a global variable in KieSession Seeing the method StatefulKnowledgeSessionImpl#setGlobal(String, Object) seems that I should set the globals before create a newInstance. Follows the StatefulKnowledgeSessionImpl#setGlobal code:

    public void setGlobal(final String identifier,
                      final Object value) {
    // Cannot set null values
    if ( value == null ) {
        return;
    }

    try {
        this.kBase.readLock();
        startOperation();
        // Make sure the global has been declared in the RuleBase
        final Map globalDefintions = this.kBase.getGlobals();
        final Class type = (Class) globalDefintions.get( identifier );
        if ( (type == null) ) {
            throw new RuntimeException( "Unexpected global [" + identifier + "]" );
        } else if ( !type.isInstance( value ) ) {
            throw new RuntimeException( "Illegal class for global. " + "Expected [" + type.getName() + "], " + "found [" + value.getClass().getName() + "]." );

        } else {
            this.globalResolver.setGlobal( identifier,
                                           value );
        }
    } finally {
        endOperation();
        this.kBase.readUnlock();
    }
}

Follows my code:

@Inject
protected PremioVisaoService premioVisaoService;

protected final KieSession createSession() {
    return this.kieBase.newKieSession();
}
protected final int process() {
    final KieSession kieSession = this.createSession();
    Object rulesFired = 0;

    try {
        //here occurs the error
        kieSession.execute(CommandFactory.newSetGlobal(PREMIO_SERVICE_GLOBAL_ID, premioVisaoService));           
    } catch(Exception e) {
        e.printStackTrace();
    }
}




    package br.com.company.brms.model.rules;

import br.com.company.brms.model.*;
import br.com.company.brms.model.premios.*;
import br.com.company.brms.model.tarifas.*;

import function br.com.company.brms.helpers.DomainUtils.getPais;
import function br.com.company.brms.helpers.DomainUtils.getUF;
import function br.com.company.brms.helpers.PremioFactory.novoPremioVisaoPercursoPadrao;
import function br.com.company.brms.helpers.CalculoTarifaHelper.calculaTaxaBasica;

global br.com.company.brms.services.PremioVisaoService premioService;


rule "Rule Example"
ruleflow-group "calculo"
salience -1
when
$averbacao : Averbacao( indicadorAvaria == Constantes.STATUS_SIM )
$taxa : TarifaPercursoVigencia( tipoTarifa == TipoTarifa.AVARIA)
then
PremioVisaoPercursoPadrao premio = novoPremioVisaoPercursoPadrao($taxa, $averbacao);
premio.setValor( calculaTaxaBasica($taxa, $averbacao) );

//insert ( premio );
premioService.inserirPremioCalculado( premio );

//System.out.println( $averbacao + " calculada com o premio: " + premio );
end

Follows below the stacktrace:

java.lang.RuntimeException: Unexpected global [premioService]
at org.drools.core.impl.StatefulKnowledgeSessionImpl.setGlobal(StatefulKnowledgeSessionImpl.java:1124)
at org.drools.core.command.runtime.SetGlobalCommand.execute(SetGlobalCommand.java:65)
at org.drools.core.impl.StatefulKnowledgeSessionImpl.execute(StatefulKnowledgeSessionImpl.java:665)
at org.drools.core.impl.StatefulKnowledgeSessionImpl.execute(StatefulKnowledgeSessionImpl.java:648)
at br.com.company.brms.services.impl.BilhetagemBpmnRunnerServiceImpl.processar(BilhetagemBpmnRunnerServiceImpl.java:87)
at br.com.company.brms.services.impl.BilhetagemBpmnRunnerServiceImpl.processarRegrasMercado(BilhetagemBpmnRunnerServiceImpl.java:52)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:317)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:183)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:96)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:260)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:94)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)
at $Proxy68.processarRegrasMercado(Unknown Source)
at br.com.company.brms.services.impl.BilhetagemProcessManagerServiceImpl.processar(BilhetagemProcessManagerServiceImpl.java:111)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:317)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:183)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:96)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:260)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:94)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)
at $Proxy69.processar(Unknown Source)
at br.com.company.brms.spi.impl.BilhetagemServiceAsyncImpl.processarPorCliente(BilhetagemServiceAsyncImpl.java:88)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:317)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:183)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
at org.springframework.aop.interceptor.AsyncExecutionInterceptor$1.call(AsyncExecutionInterceptor.java:95)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
at java.util.concurrent.FutureTask.run(FutureTask.java:138)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:662)

Tks in advance

Ivan Rodrigues
  • 441
  • 4
  • 20
  • And you did declare it in the DRL code? And the code is there in the rule base? A rule (not needing the global) does fire? – laune Sep 25 '14 at 16:02
  • @laune I updated the post with a DRL. I'm thinking very strange I run the rules during the tests and can't run it while my app up on server – Ivan Rodrigues Sep 25 '14 at 16:47
  • 1
    Which leaves the second possibility: that this DRL defining the rule base isn't deployed properly. To show that it is, add a rule that fires no matter what, don't try to set the global, and see whether that rule fires. – laune Sep 25 '14 at 16:57
  • @laune I put this line ((InternalKnowledgeBase)kieBase).addGlobal(PREMIO_SERVICE_GLOBAL_ID, PremioVisaoService.class); and the code break in kieSession.execute(CommandFactory.newFireAllRules()); with the Exception **Unknown process ID: br.com.pamcary.corporativo.bilhetagem.brms.bpmn.comercial** I move out the set of global and broke in the same line. – Ivan Rodrigues Sep 25 '14 at 17:24
  • @laune you're correct! I put the files in the same jar and the rules were executed! Tks – Ivan Rodrigues Sep 25 '14 at 19:12

2 Answers2

2

My problem was that I were looking for the DRL files in different jars. I don't know yet how I'll do this in the right way. But the problem definitely was solved.

halfer
  • 19,824
  • 17
  • 99
  • 186
Ivan Rodrigues
  • 441
  • 4
  • 20
1

I finally tracked down what the root cause of this is:

If you have a rule and you want to setGlobal for that rule, you must have the global defined in that rule (the .drl file), such as;

global net.mikeski.ProviderImpl provider

Then, kSession.setGlobal("provider", myProviderImpl); will work.

I discovered this by looking at the Drools setGlobal method in StatefulKnowledgeSessionImpl.java:

...
final Class type = (Class) globalDefintions.get( identifier );
if ( (type == null) ) {
    throw new RuntimeException( "Unexpected global [" + identifier + "]" );
} else if ( !type.isInstance( value ) ) {
    throw new RuntimeException( "Illegal class for global. " + "Expected [" + type.getName() + "], " + "found [" + value.getClass().getName() + "]." );

} else {
    this.globalResolver.setGlobal( identifier,
                                   value );
}
...
mikeb
  • 10,578
  • 7
  • 62
  • 120