Back To Basics #4: Exposing our Rules via REST (JAX-RS) using Wildfly Swarm

It is a common requirement nowadays to access to our Rule Engine Instances as REST services. On this blog post I will show an extremely simple example on how you can expose your domain specific interfaces that you can use to encapsulate KieSessions. This post builds up on my previous three posts: first, second, third.

We will be using Wildfly Swarm to create a Fat-Jar that we will be able to run without the need of installing a full blown Java EE application Server. This approach is very good when you need full control about the REST interfaces that you want to expose to  your client applications. For a more general use and for an already built in approach you can take a look a the new KIE Server, something that I will cover in future posts as well.

Introduction

One of the most interesting aspect of Drools is the fact that it can be embedded inside our services without too much overhead or complications. The fact that we can start as many instances as we want gives us the ultimate power to create and destroy KieSessions as we need.

The example that we are looking at here contains most of the pieces that you will find in real applications. And for that reason we have 3 different projects:

  1. drools-user-model: this module contains our Business Entities, for this example just the User class.
  2. drools-user-kjar: contains our rules. This package will be resolve by the KIE-CI module.
  3. drools-jax-rs: provides the JAX-RS REST endpoints for our service.

You can find the sources here: https://github.com/Salaboy/drools-workshop/tree/master/drools-rest-swarm

Dependency between modules
Dependency between modules

As you may notice the Service Layer (drools-jax-rs project) doesn’t need to know about the rules, because we are going to use KIE-CI to resolve them in the same way that we did that in my previous post. The Service Layer depends on the Model (drools-user-model) because the methods in the endpoint interface uses the User object as part of the contract of the service that is being provided. The KJAR, has an implicit dependency on the Model, just because the rules will need the Model classes to be compiled and executed, but there is no need to have a direct dependency at the project level.

The boundaries in the previous diagram is the Fat-Jar that we are going to generate with Wildfly Swarm Maven plugin, that will package us a Jar file that we can directly execute, without installing anything else in our environment besides Java.

Our (Micro)Service

The more I read about MicroServices the more I feel that Drools fits perfectly inside and around these services that we will be defining. There are several ways in which Drools can be used as part of our Services or to coordinate them based on business requirements. We will keep this example ultra simple, and for this reason, in this case, our service contract will look like this:

UserCategorizationService


@Path("users")
public interface UserCategorizationService {
  @POST
  @Consumes("application/json")
  @Produces("application/json")
  @Path("/categorize")
  public User categorizeUser(@NotNull User user);
}

Our service will be in charge of categorise our Users based on their properties. From the clients point of view, it doesn’t really matter how this categorisation is done, as soon as the user is categorised correctly. Internally from our company, we know that these categories will change from time to time, so we have chosen to use Rules to do these categorisations. We will be able to  update these rules as soon as the company decides to add, remove or even change the way that these categories are applied.

Internally the UserCategorizationServiceImpl delegates to a KieSession the responsibility of categorizing the User.


@Inject
@KReleaseId(groupId = "org.drools.workshop", artifactId = "drools-user-kjar", version = "1.0-SNAPSHOT")
@KSession
private KieSession kSession;

@Override
public User categorizeUser(User user) {
  kSession.insert(user);
  int fired = kSession.fireAllRules();
  return user;
}

Until here, nothing new right? Same as in my previous post we are using the @KReleaseId to locate the artefact that contains our Rules Definitions. Remember that to get this working, you need to compile the drools-user-kjar project before trying to access this service instance, so KIE-CI can pick it up from the Maven repository.

The only new thing here is how we are going to package, deploy and run our service. As mentioned in the introduction, we are going to use Wildfly Swarm to create a Fat Jar, and for that reason our drools-jax-rs/pom.xml contains the following extra dependencies:


 <dependency>

   <groupId>javax</groupId>

   <artifactId>javaee-web-api</artifactId>

   <version>7.0</version>

   <scope>provided</scope>

 </dependency>

 <dependency>

   <groupId>org.wildfly.swarm</groupId>

   <artifactId>wildfly-swarm-jaxrs-weld</artifactId>

   <version>${version.wildfly-swarm}</version>

 </dependency>

and the following plugin:


<plugin>
  <groupId>org.wildfly.swarm</groupId>
  <artifactId>wildfly-swarm-plugin</artifactId>
  <version>${version.wildfly-swarm}</version>
  <executions>
    <execution>
      <goals>
        <goal>package</goal>
      </goals>
    </execution>
  </executions>
</plugin>

and voila! When we package our project the wildly-swarm-plugin will create a Fat Jar that can be executed.

Interacting with our Service

Now we need to start our service first in order to start sending user to be categorised. Make you that you compile the three projects by executing mvn clean install from the root directory.

Now inside the drools-jax-rs you can go to the target/ directory and you will find the following packaged artifacts:

  • drools-jax-rs-1.0-SNAPSHOT-swarm.jar
  • drools-jax-rs-1.0-SNAPSHOT.war

We have two options here, deploy the drools-jax-rs-1.0-SNAPSHOT.war into a wildfly application server or just execute our fat jar drools-jax-rs-1.0-SNAPSHOT-swarm.jar from the terminal. The main approach of having a Fat Jar is to avoid the need of installing and configuring an Application Server. The Fat Jar is self-contained and it only requires some to start it up.

So in order to start our fat jar we only need to run:


java -jar drools-jax-rs-1.0-SNAPSHOT-swarm.jar

You should be able to see something like this: (Click to Expand)


salaboy$ <strong>java -jar drools-jax-rs-1.0-SNAPSHOT-swarm.jar&nbsp;</strong>

tmpDir: /var/folders/8j/cb5yh6795kggdy056zbdn5bh0000gn/T/

21:37:00,612 INFO&nbsp; [org.jboss.msc] (main) JBoss MSC version 1.2.6.Final

21:37:00,783 INFO&nbsp; [org.jboss.as] (MSC service thread 1-6) WFLYSRV0049: WildFly Core 2.0.0.Beta1 "Kenny" starting

2015-10-27 21:37:01,742 WARN&nbsp; [org.jboss.as.txn] (ServerService Thread Pool -- 16) WFLYTX0013: Node identifier property is set to the default value. Please make sure it is unique.

2015-10-27 21:37:01,758 INFO&nbsp; [org.wildfly.extension.io] (ServerService Thread Pool -- 18) WFLYIO001: Worker 'default' has auto-configured to 8 core threads with 64 task threads based on your 4 available processors

2015-10-27 21:37:01,770 INFO&nbsp; [org.jboss.as.naming] (ServerService Thread Pool -- 19) WFLYNAM0001: Activating Naming Subsystem

2015-10-27 21:37:01,777 INFO&nbsp; [org.jboss.as.security] (ServerService Thread Pool -- 17) WFLYSEC0002: Activating Security Subsystem

2015-10-27 21:37:01,780 INFO&nbsp; [org.jboss.as.security] (MSC service thread 1-7) WFLYSEC0001: Current PicketBox version=4.9.2.Final

2015-10-27 21:37:01,834 INFO&nbsp; [org.wildfly.extension.undertow] (ServerService Thread Pool -- 14) WFLYUT0003: Undertow 1.3.0.Beta6 starting

2015-10-27 21:37:01,834 INFO&nbsp; [org.wildfly.extension.undertow] (MSC service thread 1-5) WFLYUT0003: Undertow 1.3.0.Beta6 starting

2015-10-27 21:37:01,853 INFO&nbsp; [org.jboss.as.naming] (MSC service thread 1-3) WFLYNAM0003: Starting Naming Service

2015-10-27 21:37:01,909 INFO&nbsp; [org.xnio] (MSC service thread 1-8) XNIO version 3.3.1.Final

2015-10-27 21:37:01,919 INFO&nbsp; [org.xnio.nio] (MSC service thread 1-8) XNIO NIO Implementation Version 3.3.1.Final

2015-10-27 21:37:01,989 INFO&nbsp; [org.wildfly.extension.undertow] (MSC service thread 1-4) WFLYUT0012: Started server default-server.

2015-10-27 21:37:02,062 INFO&nbsp; [org.wildfly.extension.undertow] (MSC service thread 1-4) WFLYUT0006: Undertow HTTP listener default listening on /0:0:0:0:0:0:0:0:8080

2015-10-27 21:37:02,206 INFO&nbsp; [org.jboss.as] (Controller Boot Thread) WFLYSRV0025: WildFly Core 2.0.0.Beta1 "Kenny" started in 1658ms - Started 83 of 91 services (17 services are lazy, passive or on-demand)

2015-10-27 21:37:03,592 INFO&nbsp; [org.jboss.as.server.deployment] (MSC service thread 1-3) WFLYSRV0027: Starting deployment of "drools-jax-rs-1.0-SNAPSHOT.war" (runtime-name: "drools-jax-rs-1.0-SNAPSHOT.war")

2015-10-27 21:37:05,791 INFO&nbsp; [org.jboss.weld.deployer] (MSC service thread 1-6) WFLYWELD0003: Processing weld deployment drools-jax-rs-1.0-SNAPSHOT.war

2015-10-27 21:37:06,036 INFO&nbsp; [org.hibernate.validator.internal.util.Version] (MSC service thread 1-6) HV000001: Hibernate Validator 5.2.1.Final

2015-10-27 21:37:06,210 INFO&nbsp; [org.jboss.weld.deployer] (MSC service thread 1-4) WFLYWELD0006: Starting Services for CDI deployment: drools-jax-rs-1.0-SNAPSHOT.war

2015-10-27 21:37:06,256 INFO&nbsp; [org.jboss.weld.Version] (MSC service thread 1-4) WELD-000900: 2.3.0 (Beta3)

2015-10-27 21:37:06,284 INFO&nbsp; [org.wildfly.extension.undertow] (MSC service thread 1-7) WFLYUT0018: Host default-host starting

2015-10-27 21:37:06,290 INFO&nbsp; [org.jboss.weld.deployer] (MSC service thread 1-4) WFLYWELD0009: Starting weld service for deployment drools-jax-rs-1.0-SNAPSHOT.war

2015-10-27 21:37:06,788 WARN&nbsp; [org.kie.scanner.embedder.MavenSettings] (MSC service thread 1-8) Environment variable M2_HOME is not set

2015-10-27 21:37:07,151 INFO&nbsp; [org.kie.scanner.embedder.MavenEmbedderUtils] (MSC service thread 1-8) Not in OSGi: using plexus based maven parser

2015-10-27 21:37:08,679 INFO&nbsp; [org.drools.compiler.kie.builder.impl.KieRepositoryImpl] (MSC service thread 1-8) KieModule was added: ZipKieModule[releaseId=org.drools.workshop:drools-user-kjar:1.0-SNAPSHOT,file=/Users/salaboy/.m2/repository/org/drools/workshop/drools-user-kjar/1.0-SNAPSHOT/drools-user-kjar-1.0-SNAPSHOT.jar]

2015-10-27 21:37:08,752 WARN&nbsp; [org.jboss.weld.Validator] (Weld Thread Pool -- 3) WELD-001473: javax.enterprise.inject.spi.Bean implementation org.drools.compiler.cdi.KieCDIExtension$StatefulKSessionBean@3833f06d declared a normal scope but does not implement javax.enterprise.inject.spi.PassivationCapable. It won't be possible to inject this bean into a bean with a passivating scope (@SessionScoped, @ConversationScoped). This can be fixed by assigning the Bean implementation a unique id by implementing the PassivationCapable interface.

2015-10-27 21:37:09,040 INFO&nbsp; [org.jboss.resteasy.spi.ResteasyDeployment] (ServerService Thread Pool -- 14) Deploying javax.ws.rs.core.Application: class org.drools.workshop.config.ApplicationConfig$Proxy$_$$_WeldClientProxy

2015-10-27 21:37:09,045 INFO&nbsp; [org.jboss.resteasy.spi.ResteasyDeployment] (ServerService Thread Pool -- 14) Adding class resource org.drools.workshop.endpoint.impl.UserCategorizationServiceImpl from Application class org.drools.workshop.config.ApplicationConfig$Proxy$_$$_WeldClientProxy

2015-10-27 21:37:09,082 INFO&nbsp; [org.wildfly.extension.undertow] (ServerService Thread Pool -- 14) WFLYUT0021: Registered web context: /

<strong>2015-10-27 21:37:09,118 INFO&nbsp; [org.jboss.as.server] (main) WFLYSRV0010: Deployed "drools-jax-rs-1.0-SNAPSHOT.war" (runtime-name : "drools-jax-rs-1.0-SNAPSHOT.war")</strong>

Now your service is up and running and you can start interacting with it.

In order to do that, you can write a JavaScript client, a Java Client, or even an Android Client to call the rest services that we just exposed. Here for testing purposes I’m using Postman, a Google Chrome Extension that allows you to build HTTP requests.

creating a request with Postman
creating a request with Postman

Here you can see that I’m sending a User object (in JSON) using a POST HTTP request to the http://localhost:8080/api/users/categorize endpoint and the service is returning the same object but now with the category field set to “Adult”.

Summary

On this blog post, we saw how to put all the pieces together to get our rules bundled inside our micro-service. For this kind of scenarios we want to abstract the end user for the implementation details of our service, even hiding the underlaying technology that we are using and enabling the client to be written in any programming language that supports the creation of HTTP calls.

We saw how to use Wildfly Swarm to create a self contained package that can be executed without previously installing anything else but Java. In my next post I will go one step further and we will be using Docker to remove the need of installing Java and to make our micro service one step forward to be cloud enabled.

PS: I know that these posts looks a little bit rough and unpolished, so feel free to ask questions if there is something that is not explained in detail.

Advertisements

40 thoughts on “Back To Basics #4: Exposing our Rules via REST (JAX-RS) using Wildfly Swarm”

  1. Is the rules engine using a stateful session or stateless session ? One of my major complaints is that drools doesn’t scale horizontally that well because it doesn’t have the ability to distribute facts across multiple servers easily. Maybe this has changed ?

    Like

    1. KieSessions are stateful. Your complaint applies to every rule engine based on the Rete algorithm. Now with the new algorithm called phreak, we are one step closer to distribute the algorithm in multiple nodes. But again this might not be the best solution, due the chattines that will be generated between the nodes to perform the evaluations. In my opinion, one of the strengths of drools is that creating a new instance of the engine is extremely simple, this enables you to split your data and the coordinate sessions if needed. HTH

      Like

  2. I’ve been out of hardcore Java dev for about 3 years. I started following these tutorials as I used older versions of Drools and wanted a quick and easy working example of Drools 6. I got that, and had my eyes opened to the world of Weld, Arquillian and WildFire along the way. Things have come a long way. Fantastic job on the series of tutorials, thank you for sharing.

    Like

    1. OldGuy, your feedback is really appreciated! Help me to spread the word! By the way have you checked my latest example about the Drools Game Engine? anything else that you want to see in these blog?

      Like

  3. Thanks for a great set of articles no invoking rules as REST calls. Is it possible to create a custom UI for these rules ? I see its directly written as drl rules in the earlier articles.

    Like

    1. Yes of course you can, I would suggest you to create a rest endpoint to receive the new rules, and then you can create a web UI to generate those rules. It should be pretty easy to implement

      Like

      1. Can you suggest in what format these rules should be generated? Should they be in drl again ? I suppose generation is only one part, I will have to package and deploy too (just like you mentioned here) right ? Is there a way to completely eliminate this deploy step ?

        Like

      2. You have two options: 1) generate the rules in DRL which is the execution format 2) Generate your own model to then transform to DRL. Option 2 is a commonly used approach if you are building a very domain specific Rule Authoring UI.

        Regarding deployment, you can add your new rules to the Knowledge Base, but that’s dangerous in my opinion, becuase you never know how the newly generated rules will behave in runtime. If you are confident that you can guarrantee that the new rules will be ok, you can do that to avoid the deployment step. Having said that, and with all the new technology that we have available today, such as docker and kubernetes, you should just deploy a new version of your rules service with the newly generated rules. In that case, if something goes wrong you can quickly revert back to the old version.

        HTH

        Like

      1. I would recommend you to start simple, create a set of Rules in DRL until you figure out how your rules will look like. The next step is to make sure that you, your users can parameterize those rules, and you can achive that by just using templates, where instead of actual values in your rules you can have variables that are coming from the user input. Then if that’s not enough you can start thingking about creating your own model to generate DRL, but that all up to you to develop.

        HTH

        Like

  4. I can’t believe the amount of files maven downloaded when I installed the project that goes along with this blog (took more than ten minutes), which really worried me; with some many dependencies, something is bound to go wrong. But the Fat jar worked the very first time! I’m impressed. Thank you! Now I need to rebuild it with my rules and my restful api…. Now the errors will start popping up. Do you have any recommendations for debugging?

    Like

    1. Well you are bundling a lot of things together, that’s why they call it fatjar. You can debug as in a normal wildfly container. Look at the wildfly swarm documentation.

      Like

    2. The executable fat jar worked fine, but when I placed the war file into the EAP 7 deployments directory, I got a 404. Other war files in that directory worked fine.
      I took a wild guess and tried http://localhost:8080/drools-jax-rs-1.0-SNAPSHOT/api/users/categorize and it worked perfectly!

      Then I put my daughter’s data in (she’s 12), and no rule fired. Checking the rules.drl in the src/main/resources of drools-user-kjar, I discovered that you had made the embarrassing newbie mistake that all software developers make all the time; Line 20 should have been:
      $u: User( age = 0,…
      Not
      $u: User( age = 0,…
      Or you can add a tween rule for 11 and 12 year olds.
      (You did the range boundary correctly for the adult rule).

      Then I changed age to Double (to take into account fractions of years), and added an ArrayList of skills to User.java in drools-user-model:
      public class User {
      private String name;
      private Double age;
      private String category;
      private ArrayList skills;

      With getter and setter, of course. And I used the new variables in a rule:

      rule “Category By Age: Teenager”
      when
      $u: User( age > 12.0 && age < 18.0, category == null || == "")
      then
      $u.setCategory("Teenager");
      ArrayList skills = new ArrayList();
      skills.add(“Driving”);
      skills.add(“Reading”);
      $u.setSkills(skills);
      end

      I also changed the version from 1.0-SNAPSHOT to 1.0.
      Changing the number from Integer to Double was easy; changing the version number was a bit more involved (many pom.xml file changes)

      But the Arraylist is really giving me some problems.
      First, I can no longer use the Rete Tree view. It gives the error:

      “Unable to parse rules to show RETE view! 1 build errors’

      How do I find what the build error is?

      Second, I maven installed it anyway, and when I placed the war file in my EAP 7 depoloyments directory, the console said:
      Rule Compilation error : [Rule name=’Category By Age: Teenager’]
      org/drools/workshop/Rule_Category_By_Age$u58$_Teenager579230057.java (8:535) : The method setSkills(ArrayList) in the type User is not applicable for the arguments (String, String)
      org/drools/workshop/Rule_Category_By_Age$u58$_Teenager579230057.java (8:545) : Syntax error on token “{“, delete this token
      org/drools/workshop/Rule_Category_By_Age$u58$_Teenager579230057.java (9:569) : Syntax error on token “}”, delete this token
      org/drools/workshop/Rule_Category_By_Age$u58$_Teenager579230057.java (11:573) : Syntax error, insert “}” to complete ClassBody

      I must delete and insert the “}” token?
      What is the correct way to use ArrayLists in the “then” part of a rule?

      Finally, when I look inside my maven repository, I can see my rules inside of drools-user-kjar-1.0.jar. What I don’t understand is that inside the drools-jax-rs-1.0.war file, in the “WEB-INF\lib” directory, I can see drools-user-model-1.0.jar (which contains the User.class file). But that same lib directory, which contains so many other jar files, does not contain drools-user-kjar-1.0.jar. Where are the rules hidden inside the war file?

      Like

      1. Lol, newbie mistake… the rules were not the focus of the example, the fat jar was.. it is up to the implementor to check the validity of the rules, don’t rely on examples from the Internet. And by the way doing $u: User( age = 0,…
        Not
        $u: User( age = 0,…

        Is something that I wouldn’t recommend.
        As a Java pro you shouldn’t use ArrayList to define variables, you should use the generic interface List.

        The problem that you are having is that you are not building your modified user class and including that one inside the war, are you building all the projects with maven? And did you built everything after your changes? HTH

        Like

  5. I found the solution to the ArrayList problem:
    import java.util.ArrayList; (in the drl file)
    Duh.
    Guess I’m spoiled by Eclipse.
    It would be nice if the Rete View told my why it can’t parse.

    Like

    1. The error should be part of the plugin output.. as far as I remember. Are you still using Eclipse? I think that the plugin is not maintained anymore.. Look in the KIE workbench to see if there a new alternative for the viewer.

      Like

      1. Can you clarify about what my framework is? I’m just using drools, you just need to modify the code to update a global before calling fireAllRules.

        Like

  6. Framework? What framework? I’m just running your three Maven projects under drools-rest-swarm:
    drools-jax-rs, drools-user-kjar, and drools-user-model.

    The problem with using globals is that they are supposed to be constants; not recommended for containing time stamps.

    What I ended up doing is, at the beginning of my rules, run a rule that would update the current time in my data object (the “no-loop true” directive was very important!):
    rule “Update Market Age”
    no-loop true
    when
    drug : MedicaidDrug ()
    then
    String msg = “Updating current date and age. “+ drools.getRule().getName()+”: “+drug.toString();
    drug.addMessage(msg);
    System.out.println(msg);
    drug.updateAge();
    update(drug)
    end

    Where my MedicaidDrug class has defined:
    public void updateAge() {
    this.dateToday = new Date();
    System.out.println(“Updating to today: “+dateToday);
    this.age = Utils.getDiffYears(marketDate, this.dateToday);
    }

    Then, I can can refer to that date (age, actually) later in my rules:

    rule “Market Age more than 2 years old.”
    when
    drug : MedicaidDrug (age > 2)
    then
    String msg = “Established Drug requires data gathering. “+ drools.getRule().getName()+”: “+drug.toString();
    drug.addMessage(msg);
    System.out.println(msg);
    end

    Yes, I suppose it’s a hack, but since I can’t figure out how to access the Drools’ built-in real-time clock, it will have to do.

    Like

  7. Hi Mauricio,

    First of all, thank you very much for the article.

    I tried to follow your article with three simple maven projects (model, kjar and jax-rs). I tried to separate rules by adding them in kjar. Only kjar and jax-rs projects has dependency pointed to model project. All projects has beans.xml and kjar has kmodule.xml.

    When I tried in that arrangement and tried to run xxx-swarm-xxx.jar, I hit two issues: one is similar to the one below (complaining about KieSession) and another one is complaint that maven artifact of “model” project is not found.

    Appreciate any advice.

    [org.jboss.weld.Bootstrap] (Weld Thread Pool — 1) WELD-000119: Not generating any bean definitions from because of underlying class loading error: Type org.kie.api.runtime.KieSession from [Module “deployment.-0.0.1.jar:main” from Service Module Loader] not found. If this is unexpected, enable DEBUG logging to see the full error

    Like

    1. Hi Aung,
      it is very difficult to provide any hint without knowing exactly how your projects look like. You need to check in the swarm package if the model is included there. If it is not found there might be some issues while you declare the dependencies.

      Like

      1. Thank you very much, Mauricio.

        So far, I duplicated sample “drools-jax-rs” project, upgraded drools dependency from 6.3.0.Final to 6.5.0.Final, replaced references to sample kjar and model modules with my test kjar and model modules, replaced sample REST implementation with my test REST implementation and that modified “drools-jax-rs” project works.

        I still have to figure out what went wrong with my “drools-jax-rs” project.

        Like

      2. The question is if you are having problems resolving maven artefacts.
        Because if that’s the problem it might be a configuration missing so aether knows from where to pick up the dependencies

        Like

      3. Hi Mauricio,

        To share with you about my finding…..The only difference I see so far between your sample project and my test project is that missing packaging info in pom.xml file. Initially I didn’t specified project’s packaging as “war”. After I specified packaging as “war” in pom.xml file, my custom “drools-jax-rs” project works.

        This is what I did. I clone your sample “drools-jax-rs” project and replaced your kjar and model references with my custom kjar and model references while sticking to drools-6.3.0.Final. That worked. So, I upgraded drools to 6.5.0 and it still worked. After that, I compared your sample “drools-jax-rs” project and my test project piece by piece.

        Thank you very much for your kind guidance. Have a nice weekend ahead.

        Warm regards,

        Aung

        Like

    2. Yes, it’s all working. I get docker image with drools service working well.

      Now, I’m trying to use Kie Scanner but it’s failing. The main purpose is to get KieScanner scanning kjar artifact (RELEASE version) periodically and get rule automatically updated.

      I tried to get Kie Scanner from KieServices which in run was created by KieServices.Factory.get() method. I tried to use injected KieContainer but it failed. I also tried to use KieContainer through KieServices but it somehow is failing too.

      Appreciate any guidance.

      Like

      1. Well but how is it failing? Did you configured where the kie scanner is looking for your rules? Remember that it uses maven to do resolutions so it requires a local or remote maven repo to resolve your artifacts

        Like

      2. I have custom maven repository working fine.

        It’s failing at kjar module dependency resolution through kieService object’s newReleasedId method. When I used open-ended version, it worked. When I released new kjar version, Kie Scanner picked it up and worked fine. When I used “RELEASE” version, it complaint about that and resolution failed.

        Like

      3. Hope you had a great weekend, Mauricio.

        I tried latest drools version – 7.0.0.Final, and 7.1.0.Beta3 but they don’t work well for dependency resolution through “RELEASE” and “LATEST” version label. I need to stick to open-ended version label at the moment, I guess.

        Like

      4. I reported my issue through JBoss JIRA board. I believe, maven arrangement is fine because resolution through open-ended version label works well for starting KieContainer instance through base kjar version and also getting new kjar version through my maven repository.

        Like

  8. Hi Mauricio,
    I implemented an enhanced version of your three maven projects (drools-jax-rs, drools-kjar, and drools-model) under a parent. On my local MS Windows 10 box, the resulting war file works great (running all my rules on my complex data object when I post some JSON to the RESTful end point). But when I place that same war file in the EAP deployment directory on an AWS box running Red Hat Enterprise Linux Server release 6.9 (Santiago), it doesn’t deploy. I’m running EAP 7.0 and Java 1.8.0 on both machines (I wrote a HelloEAP project whose war file works fine on both machines). What could cause such strange behavior? Does Maven/EAP/Drools work differently on Windows and Linux operating systems?

    The stack trace on the AWS Linux box:

    [root deployments]# more drools-jax-rs-1.0.war.failed
    “{\”WFLYCTL0080: Failed services\” => {\”jboss.deployment.unit.\\\”drools-jax-rs-1.0.war\\\”.WeldStartService\” => \”org.jboss.m
    sc.service.StartException in service jboss.deployment.unit.\\\”drools-jax-rs-1.0.war\\\”.WeldStartService: Failed to start service
    Caused by: org.jboss.weld.exceptions.DefinitionException: Exception List with 1 exceptions:
    Exception 0 :
    java.lang.RuntimeException: Cannot find KieModule: org.mycompany:drools-kjar:1.0
    at org.drools.compiler.kie.builder.impl.KieServicesImpl.newKieContainer(KieServicesImpl.java:117)
    at org.drools.compiler.kie.builder.impl.KieServicesImpl.newKieContainer(KieServicesImpl.java:111)
    at org.drools.compiler.cdi.KieCDIExtension.afterBeanDiscovery(KieCDIExtension.java:287)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.jboss.weld.injection.StaticMethodInjectionPoint.invoke(StaticMethodInjectionPoint.java:88)
    at org.jboss.weld.injection.MethodInvocationStrategy$SpecialParamPlusBeanManagerStrategy.invoke(MethodInvocationStrategy.java:144)
    at org.jboss.weld.event.ObserverMethodImpl.sendEvent(ObserverMethodImpl.java:309)
    at org.jboss.weld.event.ExtensionObserverMethodImpl.sendEvent(ExtensionObserverMethodImpl.java:124)
    at org.jboss.weld.event.ObserverMethodImpl.sendEvent(ObserverMethodImpl.java:287)
    at org.jboss.weld.event.ObserverMethodImpl.notify(ObserverMethodImpl.java:265)
    at org.jboss.weld.event.ObserverNotifier.notifySyncObservers(ObserverNotifier.java:271)
    at org.jboss.weld.event.ObserverNotifier.notify(ObserverNotifier.java:260)
    at org.jboss.weld.event.ObserverNotifier.fireEvent(ObserverNotifier.java:154)
    at org.jboss.weld.event.ObserverNotifier.fireEvent(ObserverNotifier.java:148)
    at org.jboss.weld.bootstrap.events.AbstractContainerEvent.fire(AbstractContainerEvent.java:53)
    at org.jboss.weld.bootstrap.events.AbstractDefinitionContainerEvent.fire(AbstractDefinitionContainerEvent.java:42)
    at org.jboss.weld.bootstrap.events.AfterBeanDiscoveryImpl.fire(AfterBeanDiscoveryImpl.java:61)
    at org.jboss.weld.bootstrap.WeldStartup.deployBeans(WeldStartup.java:422)
    at org.jboss.weld.bootstrap.WeldBootstrap.deployBeans(WeldBootstrap.java:83)
    at org.jboss.as.weld.WeldStartService.start(WeldStartService.java:95)
    at org.jboss.msc.service.ServiceControllerImpl$StartTask.startService(ServiceControllerImpl.java:1948)
    at org.jboss.msc.service.ServiceControllerImpl$StartTask.run(ServiceControllerImpl.java:1881)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)
    \”}}”

    Like

    1. No idea about EAP that’s a paid product, in this blog
      Only open source stuff 😉 . The key of the error is in : KieModule: org.mycompany:drools-kjar:1.0 . It might aether trying to resolve that from the local maven repo and in AWS you don’t have a local maven repo , that sounds like the probable cause of the issue. HTH

      Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s