I am trying to load a rule from a String in Drools 6 like this:
// the rule
def drl = '''
dialect "mvel"
rule "Person is over 18"
when
$person : Person(age > 18)
then
System.out.println("Person is "+$person.name);
end
'''
// setup for rule
KieServices kieServices = KieServices.Factory.get()
KieFileSystem kfs = kieServices.newKieFileSystem()
kfs.write( "src/main/resources/simple.drl",
kieServices.getResources().newReaderResource( new StringReader(drl) ) )
KieBuilder kieBuilder = kieServices.newKieBuilder( kfs ).buildAll()
// check there have been no errors for rule setup
Results results = kieBuilder.getResults();
if( results.hasMessages( Message.Level.ERROR ) ){
println( results.getMessages() )
throw new IllegalStateException( "### errors ###" )
}
KieContainer kieContainer =
kieServices.newKieContainer( kieBuilder.getKieModule().getReleaseId() )
KieSession kieSession = kieContainer.newKieSession()
// insert facts and fire rules
kieSession.insert(new Person("Jon Doe", 21))
kieSession.insert(new Person("Jon Darcy", 1))
kieSession.fireAllRules()
kieSession.dispose()
#Immutable
class Person {
String name
int age
}
What I wanted to happen is getting the person name printed out. By attaching eventlistener and logger I can see that the facts are added and asserted. By having an error in the drl I can be sure the rule is seen and compiled. But the rule never fires.
I am pretty sure there is jsut a stupid little mistake somewhere in the code. Can somebody help me?
Getting a KieBase from the KieContainer and creating the KieSession from that is what works for me:
KieContainer kieContainer =
kieServices.newKieContainer(kieServices.getRepository().getDefaultReleaseId() );
KieBase kieBase = kieContainer.getKieBase();
KieSession kieSession = kieBase.newKieSession();
But your code is working, too - at least after doing it all in Java, and making sure that Person and the DRL file are in the same package.
String drl = "package drlstring;\n" +
"dialect 'mvel'\n" +
"rule Person_is_over_18\n" +
"when\n" +
"$person : Person(age > 18)\n" +
"then\n" +
"System.out.println(\"Person is \"+$person.getName());\n" +
"end";
// setup for rule
KieServices kieServices = KieServices.Factory.get();
KieFileSystem kfs = kieServices.newKieFileSystem();
kfs.write( "src/main/resources/simple.drl",
kieServices.getResources().newReaderResource( new StringReader(drl) ) );
KieBuilder kieBuilder = kieServices.newKieBuilder( kfs ).buildAll();
// check there have been no errors for rule setup
Results results = kieBuilder.getResults();
if( results.hasMessages( Message.Level.ERROR ) ){
System.out.println( results.getMessages() );
throw new IllegalStateException( "### errors ###" );
}
KieContainer kieContainer =
kieServices.newKieContainer( kieBuilder.getKieModule().getReleaseId() );
KieSession kieSession = kieContainer.newKieSession();
// insert facts and fire rules
kieSession.insert(new Person("Jon Doe", 21));
kieSession.insert(new Person("Jon Darcy", 1));
kieSession.fireAllRules();
kieSession.dispose();
If you want to continue with your Scala setup, narrow the possible causes for the failure to fire down by adding a rule with an empty condition:
rule hello
when then
System.out.println( "Hello!" );
end
I think it is the Scala definition of class Person that isn't recognized by the Drools engine.
Related
I'm trying to integrate drools kie workbench with java application. I'm Using jboss-as-7.1.1.Final as my workbench. Here is the rule definition:
package com.sample;
rule "set isEligible"
ruleflow-group "sample"
lock-on-active true
when
$p : Student(gpa > 2.0)
then
System.out.println("GPA is greater than 2..");
$p.setEligible(true);
end
From the java application i'm passing the student POJO object to the kieSession object and firing up the rules.
Here is the code:
Student s = new Student();
s.setName("Virat");
s.setGpa(5.0f);
URL u = new URL("http://localhost:8080/kie-wb-distribution-wars-6.2.0.Final-jboss-as7/kie-wb.html#%5Bnull%5D?path_uri=default://master#com/sample/src/main/resources/com/sample/sampleDRL.drl&file_name=sampleDRL.drl&has_version_support=true");
KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
kbuilder.add( ResourceFactory.newUrlResource(u), ResourceType.DRL );
kbuilder.hasErrors();
if (kbuilder.hasErrors() ) {
System.out.println( kbuilder.getErrors() );
}
kbuilder.getKnowledgePackages();
KieBase kieBase = kieContainer.getKieBase();
KieSession kieSession = kieBase.newKieSession();
kieSession.insert(s);
kieSession.fireAllRules();
I'm able to connect to the workbench repository (com:sample:1.0) from the java app. But the problem is, i'm getting the following exception while executing the rule:
[8,0]: [ERR 107] Line 8:0 mismatched input '<' expecting one of the following tokens: '[package, import, global, declare, function, rule, query]'.
[0,0]: Parser returned a null Package
I don't know where i went wrong (because no where i have used '<' symbol).
Ask me for any missing detail. Any help on this would be greatly appreciated. Thank you.
I have scenario in my project to make dynamic rule and store it into brms rule server. I've try to using KieFileSystem to write my String object become drl file, but I still cannot store my rule into rule engine server when I open the Business Central.
Here is my code from my Java main class :
// I called my artifact repository from BRMS server
String url = "http://192.168.0.1:8080/business-central/maven2/com/test/1.0/test-1.0.jar";
KieServices ks = KieServices.Factory.get();
KieRepository kr = ks.getRepository();
UrlResource urlResource = (UrlResource) ks.getResources().newUrlResource(url);
urlResource.setUsername("username");
urlResource.setPassword("password");
urlResource.setBasicAuthentication("enabled");
InputStream is = urlResource.getInputStream();
KieModule kModule = kr.addKieModule(ks.getResources().newInputStreamResource(is));
KieFileSystem kfs = ks.newKieFileSystem();
String rule = "package com.test; \n"
+ "rule \"rule_1\" \n"
+ "when \n"
+ "then \n"
+ "System.out.println(\"rule_1 fired\"); \n"
+ "end";
kfs.write("src/main/resources/rules/generatedRule.drl", rule);
KieBuilder kb = ks.newKieBuilder(kfs).setDependencies(kModule).buildAll();
When I run this program, I cannot find my generated rule in my rule directory project in Business Central.
Thank you
I am trying to read .xlsx file with rules using kie api 6.
However I get this exception
java.lang.RuntimeException: Resource does not have neither a source nor a target path. Impossible to add it to the bundle. P
lease set either the source or target name of the resource before adding it.null
at org.drools.compiler.kie.builder.impl.KieFileSystemImpl.write(KieFileSystemImpl.java:83)
at com.project.watch.validator.RuleValidator.isValidRuleKieNew(RuleValidator.java:71)
at com.project.watch.validator.RuleValidator.isValidRule(RuleValidator.java:37)
at com.project.watch.core.WatchDir$ValidateFileRunnable.run(WatchDir.java:177)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:304)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:
178)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:745)
The code looks like this
try {
KieServices ks = KieServices.Factory.get();
KieFileSystem kfs = ks.newKieFileSystem();
kfs.write(ks.getResources().newInputStreamResource(Files.newInputStream(p, StandardOpenOption.READ)));
KieBuilder kb = ks.newKieBuilder(kfs);
if (kb.getResults().getMessages(Level.ERROR).size() != 0) {
logger.lifecycle("Invalid file: {}.", kb.getResults().getMessages());
return false;
}
} catch (Exception e) {
logger.lifecycle("UNEXPECTED ERROR DURING VALIDATION -------------- ", e);
return false;
}
logger.lifecycle("Valid file: {}.", p);
return true;
}
It fails on kfs.write by the way.
I also checked the path to file by displaying it in console
Attempt to process rule file: D:\PROJECT_FOLDER\project\src\testInteg\resources\rules\rule.xlsx
and it is a correct path.
What's the problem? I am using 6.3 Final version.
I recommend this mantra, assuming your String p contains the path name as shown:
FileInputStream fis = new FileInputStream( p );
kfs.write( "src/main/resources/rule.xslx",
kieServices.getResources().newInputStreamResource( fis ) );
There are some other forms for write to the KieFileSystem, but I find that this is easy to use. You may derive the rule.xslx from p, using Java's API for path names.
I'm using Amazon's Java client for S3 to access Swisscom's dynamic storage as well as S3 Ninja.
Creating buckets and putting objects works with S3 Ninja (i.e., on localhost). Creating buckets seems to work in the cloud, but putting objects doesn't:
Oct 30 12:04:44 SquaccDevLog 5751ff25-6661-43d6-92ba-91b7c0cf7c55/[App/0]: com.amazonaws.services.s3.model.AmazonS3Exception: Access Denied (Service: Amazon S3; Status Code: 403; Error Code: AccessDenied; Request ID: null)
I may be missing something wrt https://docs.developer.swisscom.com/services/offerings/dynamic.html#authentication - but what (cf. static initializer in the code below)?
Thanks,
Paul
PS: The code below is for the most part (i.e., main and below) Amazon's S3 Java example.
/*
* The MIT License
*
* Copyright (c) 2015 Squeng AG
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package models.s3;
import java.io.*;
import java.util.*;
import play.libs.*;
import com.amazonaws.*;
import com.amazonaws.auth.*;
import com.amazonaws.services.s3.*;
import com.amazonaws.services.s3.model.*;
import com.fasterxml.jackson.databind.node.*;
/**
* Copyright © 2015 Squeng AG
*
* #author Paul
*/
public final class S3Factory
{
private S3Factory()
{
// disable instance construction
}
// FIXME: move to configuration eventually, one for development, testing, and production each
private static final AmazonS3 client;
static {
String vss = System.getenv( "VCAP_SERVICES" );
if ( vss != null ) {
ClientConfiguration clientConfig = new ClientConfiguration();
clientConfig.setProtocol( Protocol.HTTPS );
ObjectNode VCAP_SERVICES = (ObjectNode)Json.parse( vss );
ObjectNode dynstrg = (ObjectNode)VCAP_SERVICES.get( "dynstrg" ).get( 0 );
ObjectNode credentials = (ObjectNode)dynstrg.get( "credentials" );
BasicAWSCredentials awsCreds = new BasicAWSCredentials( credentials.get( "accessKey" ).asText(), credentials.get( "sharedSecret" ).asText() );
client = new AmazonS3Client( awsCreds, clientConfig );
client.setEndpoint( credentials.get( "accessHost" ).asText() );
client.setS3ClientOptions( (new S3ClientOptions()).withPathStyleAccess( true ) );
} else {
ClientConfiguration clientConfig = new ClientConfiguration();
clientConfig.setProtocol( Protocol.HTTP );
BasicAWSCredentials awsCreds = new BasicAWSCredentials( "AKIAIOSFODNN7EXAMPLE", "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY" );
client = new AmazonS3Client( awsCreds, clientConfig );
client.setEndpoint( "localhost:9444/s3" );
client.setS3ClientOptions( (new S3ClientOptions()).withPathStyleAccess( true ) );
}
}
public static AmazonS3 createBucketIfNeedBe( String bucket )
{
if ( !client.doesBucketExist( Objects.requireNonNull( bucket ) ) ) {
// FIXME: barely good enough for only one JVM
synchronized ( bucket.intern() ) {
if ( !client.doesBucketExist( bucket ) ) {
client.createBucket( bucket );
}
}
}
return client;
}
public static void main( String[] args )
throws IOException
{
String bucketName = "my-first-s3-bucket-" + UUID.randomUUID();
String key = "MyObjectKey";
System.out.println( "===========================================" );
System.out.println( "Getting Started with Amazon S3" );
System.out.println( "===========================================\n" );
try {
/*
* Create a new S3 bucket - Amazon S3 bucket names are globally unique, so once a bucket name has been taken by any user, you can't create another bucket with that same name.
*
* You can optionally specify a location for your bucket if you want to keep your data closer to your applications or users.
*/
System.out.println( "Creating bucket " + bucketName + "\n" );
client.createBucket( bucketName );
/*
* List the buckets in your account
*/
// System.out.println( "Listing buckets" );
// for ( Bucket bucket : client.listBuckets() ) {
// System.out.println( " - " + bucket.getName() );
// }
// System.out.println();
/*
* Upload an object to your bucket - You can easily upload a file to S3, or upload directly an InputStream if you know the length of the data in the stream. You can also specify your own metadata when uploading to S3, which allows you set a
* variety of options like content-type and content-encoding, plus additional metadata specific to your applications.
*/
System.out.println( "Uploading a new object to S3 from a file\n" );
client.putObject( new PutObjectRequest( bucketName, key, createSampleFile() ) );
/*
* Download an object - When you download an object, you get all of the object's metadata and a stream from which to read the contents. It's important to read the contents of the stream as quickly as possibly since the data is streamed directly
* from Amazon S3 and your network connection will remain open until you read all the data or close the input stream.
*
* GetObjectRequest also supports several other options, including conditional downloading of objects based on modification times, ETags, and selectively downloading a range of an object.
*/
System.out.println( "Downloading an object" );
S3Object object = client.getObject( new GetObjectRequest( bucketName, key ) );
System.out.println( "Content-Type: " + object.getObjectMetadata().getContentType() );
displayTextInputStream( object.getObjectContent() );
/*
* List objects in your bucket by prefix - There are many options for listing the objects in your bucket. Keep in mind that buckets with many objects might truncate their results when listing their objects, so be sure to check if the returned
* object listing is truncated, and use the AmazonS3.listNextBatchOfObjects(...) operation to retrieve additional results.
*/
// System.out.println( "Listing objects" );
// ObjectListing objectListing = client.listObjects( new ListObjectsRequest().withBucketName( bucketName ).withPrefix( "My" ) );
// for ( S3ObjectSummary objectSummary : objectListing.getObjectSummaries() ) {
// System.out.println( " - " + objectSummary.getKey() + " " + "(size = " + objectSummary.getSize() + ")" );
// }
// System.out.println();
try ( Scanner s = new Scanner( System.in ) ) {
System.out.println( "Unter data/s3 sollten das Bucket und das Object nun ersichtlich sein." );
System.out.println( "Nach dem Drücken der Enter/Return-Taste werden sie wieder gelöscht ..." );
s.nextLine();
}
/*
* Delete an object - Unless versioning has been turned on for your bucket, there is no way to undelete an object, so use caution when deleting objects.
*/
System.out.println( "Deleting an object\n" );
client.deleteObject( bucketName, key );
/*
* Delete a bucket - A bucket must be completely empty before it can be deleted, so remember to delete any objects from your buckets before you try to delete them.
*/
System.out.println( "Deleting bucket " + bucketName + "\n" );
client.deleteBucket( bucketName );
} catch ( AmazonServiceException ase ) {
System.out.println( "Caught an AmazonServiceException, which means your request made it " + "to Amazon S3, but was rejected with an error response for some reason." );
System.out.println( "Error Message: " + ase.getMessage() );
System.out.println( "HTTP Status Code: " + ase.getStatusCode() );
System.out.println( "AWS Error Code: " + ase.getErrorCode() );
System.out.println( "Error Type: " + ase.getErrorType() );
System.out.println( "Request ID: " + ase.getRequestId() );
ase.printStackTrace( System.out );
} catch ( AmazonClientException ace ) {
System.out.println( "Caught an AmazonClientException, which means the client encountered " + "a serious internal problem while trying to communicate with S3, " + "such as not being able to access the network." );
System.out.println( "Error Message: " + ace.getMessage() );
ace.printStackTrace( System.out );
}
}
/**
* Creates a temporary file with text data to demonstrate uploading a file to Amazon S3
*
* #return A newly created temporary file with text data.
*
* #throws IOException
*/
private static File createSampleFile()
throws IOException
{
File file = File.createTempFile( "aws-java-sdk-", ".txt" );
file.deleteOnExit();
Writer writer = new OutputStreamWriter( new FileOutputStream( file ) );
writer.write( "abcdefghijklmnopqrstuvwxyz\n" );
writer.write( "01234567890112345678901234\n" );
writer.write( "!##$%^&*()-=[]{};':',.<>/?\n" );
writer.write( "01234567890112345678901234\n" );
writer.write( "abcdefghijklmnopqrstuvwxyz\n" );
writer.close();
return file;
}
/**
* Displays the contents of the specified input stream as text.
*
* #param input
* The input stream to display as text.
*
* #throws IOException
*/
private static void displayTextInputStream( InputStream input )
throws IOException
{
BufferedReader reader = new BufferedReader( new InputStreamReader( input ) );
while ( true ) {
String line = reader.readLine();
if ( line == null )
break;
System.out.println( " " + line );
}
System.out.println();
}
}
Did you check to put the "PathStyleAccess" for accessing the Swisscom Object Storage ?
Most of the compatible S3 interfaces need this flag on:
This seems to work on my side; here some snippets:
S3ClientOptions options = new S3ClientOptions();
options.setPathStyleAccess(true);
AmazonS3Client client = new AmazonS3Client(new BasicAWSCredentials(uid, secret));
client.setEndpoint("https://ds31s3.swisscom.com");
client.setS3ClientOptions(options);
/*
* Creating a new bucket in the
*/
String newBucket = "mybucket";
client.createBucket(newBucket, "Standard");
/*
* Add a new object
*/
client.putObject(newBucket, "CloudFoundry1.png", objectFile);
client.putObject(newBucket, "CloudFoundry2.png", objectFile);
/*
* List existing objects
*/
ObjectListing objects = client.listObjects("mybucket");
for (S3ObjectSummary summary : objects.getObjectSummaries()) {
System.out.println(summary.getKey()+ " "+summary.getOwner());
}
Hope this helps;
Best
Marco
I have this class, that reads rule files, insert facts and run rules.
public class RuleRunner {
private KieServices kieServices = KieServices.Factory.get();
public enum RuleType {
XLS,
DRL;
}
private void prepareSession(String ruleResource, RuleType type) {
KieFileSystem kieFileSystem = kieServices.newKieFileSystem();
Resource resource = kieServices.getResources().newClassPathResource(ruleResource);
switch(type) {
case XLS: {
resource.setResourceType(ResourceType.DTABLE);
break;
}
case DRL: {
resource.setResourceType(ResourceType.DRL);
break;
}
}
kieFileSystem.write(resource);
KieBuilder kieBuilder = kieServices.newKieBuilder(kieFileSystem);
kieBuilder.buildAll();
if (hasErrors(kieBuilder)) {
System.out.println("Failed to build!");
return;
}
}
private boolean hasErrors(KieBuilder builder) {
if (builder.getResults().getMessages().size() > 0) {
return true;
}
return false;
}
public void runRules(Object[] facts, GlobalVariable[] variables, String ruleResource, RuleType type) {
prepareSession(ruleResource, type);
KieContainer kieContainer = kieServices.newKieContainer(kieServices.getRepository().getDefaultReleaseId());
KieSession kieSession = kieContainer.newKieSession();
for (GlobalVariable variable: variables) {
kieSession.setGlobal(variable.getVariableName(), variable);
}
for(Object fact: facts) {
kieSession.insert(fact);
}
kieSession.fireAllRules();
kieSession.dispose();
}
}
And I have this rule
package com.pack.drools.apps;
import com.pack.drools.apps.domain.Person;
import com.pack.drools.apps.domain.GlobalVariable;
global GlobalVariable result
rule "if person has less that 10 cash then hes poor"
when
$person:Person(cash < 10)
then
result.setResult(-1);
end
rule "if person has more than 90 cash then hes rich"
when
$person:Person(cash > 90)
then
result.setResult(-2);
end
rule "if person has more than 10 and less than 90 then hes average"
when
$person:Person(cash >= 10 && cash <= 90)
then
result.setResult(-3);
end
However when I try to run my application
package pack.rup.drools.apps;
import pack.rup.drools.apps.core.RuleRunner;
import pack.rup.drools.apps.core.RuleRunner.RuleType;
import pack.rup.drools.apps.domain.GlobalVariable;
import pack.rup.drools.apps.domain.Person;
public class Main {
private static final String DEFAULT_PACKAGE = "pack/rup/drools/apps/";
private static final String XLS_FILE = DEFAULT_PACKAGE + "rule.xls";
private static final String DRL_FILE = DEFAULT_PACKAGE + "rule.drl";
public static void main(String[] args) {
RuleRunner ruleRunner = new RuleRunner();
// build fact
Person person = new Person();
person.setName("John");
person.setCash(100);
GlobalVariable result = new GlobalVariable();
result.setVariableName("result");
// ruleRunner.runRules(new Object[] { person }, new GlobalVariable[] { result }, XLS_FILE, RuleType.XLS);
ruleRunner.runRules(new Object[] { person }, new GlobalVariable[] { result }, DRL_FILE, RuleType.DRL);
System.out.println("Rule result: " + result.getResult());
}
}
my log looks like this
10:13:00.974 [main] INFO o.d.c.k.b.impl.KieRepositoryImpl - KieModule was added: MemoryKieModule[releaseId=org.default:arti
fact:1.0.0-SNAPSHOT]
10:13:00.982 [main] INFO o.d.c.k.b.impl.ClasspathKieProject - Found kmodule: file:/D:/workTestProjects/simpleDroolsApps/sda
-core/build/resources/main/META-INF/kmodule.xml
10:13:00.982 [main] DEBUG o.d.c.k.b.impl.ClasspathKieProject - KieModule URL type=file url=/D:/workTestProjects/simpleDrools
Apps/sda-core/build/resources/main
10:13:01.026 [main] WARN o.d.c.k.b.impl.ClasspathKieProject - Unable to find pom.properties in /D:/workTestProjects/simpleD
roolsApps/sda-core/build/resources/main
10:13:01.027 [main] WARN o.d.c.k.b.impl.ClasspathKieProject - As folder project tried to fall back to pom.xml, but could no
t find one for null
10:13:01.027 [main] WARN o.d.c.k.b.impl.ClasspathKieProject - Unable to load pom.properties from/D:/workTestProjects/simple
DroolsApps/sda-core/build/resources/main
10:13:01.027 [main] WARN o.d.c.k.b.impl.ClasspathKieProject - Cannot find maven pom properties for this project. Using the
container's default ReleaseId
10:13:01.027 [main] DEBUG o.d.c.k.b.impl.ClasspathKieProject - Discovered classpath module org.default:artifact:1.0.0-SNAPSH
OT
10:13:01.028 [main] INFO o.d.c.k.b.impl.KieRepositoryImpl - KieModule was added: FileKieModule[releaseId=org.default:artifa
ct:1.0.0-SNAPSHOT,file=D:\workTestProjects\simpleDroolsApps\sda-core\build\resources\main]
10:13:01.035 [main] WARN o.d.c.k.b.impl.AbstractKieModule - No files found for KieBase defaultKieBase, searching folder D:\
workTestProjects\simpleDroolsApps\sda-core\build\resources\main
10:13:01.131 [main] DEBUG o.drools.core.impl.KnowledgeBaseImpl - Starting Engine in PHREAK mode
Exception in thread "main" java.lang.RuntimeException: Unexpected global [result]
at org.drools.core.impl.StatefulKnowledgeSessionImpl.setGlobal(StatefulKnowledgeSessionImpl.java:1163)
at pack.rup.drools.apps.core.RuleRunner.runRules(RuleRunner.java:57)
at pack.rup.drools.apps.Main.main(Main.java:27)
:sda-core:run FAILED
It seems that you must use a particular directory when writing DRL or XLS resources to the KieFileSystem. Try
String filename = ...; // code that set filename to (e.g.) rule.drl
kieFileSystem.write( "src/main/resources/" + filename, resource );
Also, in your DRL you have
import com.pack.drools.apps.domain....
whereas in Main.java there is
import pack.rup.drools.apps.domain....
These imports should be from the same package.
Edit To test what globals are in the session:
Globals globals = kieSession.getGlobals();
System.out.println( globals.getGlobalKeys() );
We spent 2 days with my colleague and finally figured out that "Unexpected global" error happens when your DRL is empty because of compilation errors, that's why addGlobal() can't find any global declaration.
Once DRL compiler does not throw any exception on errors, instead you can check it yourself using:
if (kieBuilder.hasErrors()) {
System.out.print( kieBuilder.getErrors() );
}
If you insert a global, you must consume it. For example, if you have:
ArrayList<Thing> myThings = new ArrayList<Thing>();
kSession.setGlobal("myThings", myThings);
In your DRL files, you must have at least one matching:
global ArrayList<Thing> myThings;
Otherwise, you get:
java.lang.RuntimeException: Unexpected global [myThings]
at org.drools.core.impl.StatefulKnowledgeSessionImpl.setGlobal(StatefulKnowledgeSessionImpl.java:1200)
at com.sample.ThingTest.test(ThingTest.java:37)