Tuesday, 8 July 2008

Building from command line in JRules 6.7

In my post last week [2 years of JRules] I had a bit of a moan that JRules didn't have out of the box functionality to build a ruleset from outside of eclipse. Ironically a couple of days after I posted that up I was trying out JRules 6.7 and it appears ILOG have pulled their finger out and provided a way of building a ruleset from outside the eclipse rule studio.

It works by running eclipse in headless mode and providing a script location as one of the command line arguments. The given script is written in javascript and calls the JRules API.

For those of you who just want to dive straight into the code here are the downloads:

rule-builder-script.xml
- this is an ant build file to run eclipse in headless mode and invoke the script

RulesBuild.js - this is the script that builds and extracts a ruleset by calling the JRules API.

I won't go through the ant script in detail, but if you are new to ant, have a look at the ant user manual.

The target "BuildSomething" is a dummy target for you to change. Here are the parameters that need to be updated:

projectName - This is the name of the project which contains the main rule flow.
extractorName - Name of extractor to use
archiveFile - path of where to save the ruleset jar
workspace.dir - path to the eclipse workspace which contains your rule projects

The other target "buildAndExtractRuleset" which BuildSomething calls, calls the macrodef task "headless.appication" which actually fires up eclipse in headless mode. The variables in here that need to be updated are:

script.location - path to RulesBuild.js
eclipse.home - the install path to eclipse

Once you update these variables you can just run the task BuildSomething (command line: ant -f rule-builder-script.xml BuildSomething) .

The script will take a bit of time to run depending on the number of rules in your projects, and once you see RulesBuild.js ENDED , your ruleset jar should be in the location of archiveFile.
Now let's look at the script. Firstly get to know the global variables that are accessible in the script:





























Global Variable NameJava TypeDescription
workspaceorg.eclipse.core.resources.IWorkspaceProvides access to the projects
ruleModelilog.rules.studio.model.IlrRuleModelProvides access to the Rule Studio Model
modelHelperilog.rules.studio.javascript.dom.IlrModelHelperModifies to Rule Studio rule model
importHelperilog.rules.studio.javascript.dom.IlrImportHelperImports projects into the workspace
buildHelperilog.rules.studio.javascript.dom.IlrBuildHelperBuilds the projects of the workspace
extractorHelperilog.rules.studio.javascript.dom.IlrExtractorHelperExtracts the ruleset archives from the rule projects


The function main() is the entry point to the script. This reads in the arguments , turns off auto-building , calls the build functions, calls the generate archive action and then prints a report of all the projects built.

I'll skip to the function build in ArchiveBuilder (line 166):

First all the projects in the workspace are cleaned and refreshed:

Utilities.println("Begin Clean...");
buildHelper.clean ();
Utilities.println("End Clean...");

Utilities.println("Begin Refresh...");
for each( project in workspace.getRoot().getProjects() ) {
project.refreshLocal(2, null);
}
Utilities.println("End Refresh.");

You could add some code before this to open projects that are closed in the workspace.


Then a full build is called and for each project, a report is generated:

Utilities.println("Begin Full Build...");
buildHelper.fullBuild();
Utilities.println("End Full Build");

for each( project in workspace.getRoot().getProjects() ) {
var report = new BuildReport (project,buildHelper.getBuildErrors(project, buildHelper.SEVERITY_ERROR));
this.reports.push (report);
}


That's the build complete, i.e. the ilr has been created for all your business rules, decision tables, ruleflows, etc.

Now all this ilr has to be packaged up into a jar.

The generate function(line 192) is called to to this.


var rp = ruleModel.getRuleProject(ruleprojectName) ;
var jarfile = archivePath;
Utilities.println("Extracting ruleset archive " + rp.getName() + " with extractor '" + extractor + "'");
extractorHelper.extract(rp,jarfile,extractor);
Utilities.println("Successfully extracted in " + (new java.io.File (jarfile)).getAbsolutePath());

The extractorHelper is called to extract the jar. If you don't have an extractor, the extract method is overloaded to also generate a ruleset just with a RuleProject and a path location.

That's about it. I really advise you to go through the RulesBuild.js and look at the JRules API documentation. If you have any questions post me a comment.

30 comments:

  1. Thanks for the useful post.

    Command line synchronization and build are features that were requested pretty soon after the release of 6.0 and we added them as quickly as we could.

    Dan
    http://blogs.ilog.com/brms/

    ReplyDelete
  2. Thanks for the feedback Dan. The ability to build from a script will hopefully simplify our build process.

    And hopefully it will work on unix, as our old approach of using a plugin to call eclipse in headless mode never worked.

    ReplyDelete
  3. Is there some way to build the rule projects using scripts without having eclipse installed?

    ReplyDelete
  4. What modifications do I need to make if i dont have an extractor? What shoul i pass as parameter if I dont have an extractor defined?

    ReplyDelete
  5. Hi Sudhiranjan,

    In answer to your first question, you do need to have eclipse installed for the script to work. The script fires up eclipse in headless mode, hence eclipse must be installed.

    In your next question you asked what to do if you do not have an extractor.

    The IlrExctractorHelper has an overloaded extract method which doesn't need an extractor as an arguement:

    extract(IlrRuleProject ruleProject, String path)

    (See line 199 in RulesBuild.js and change this)

    For more info See: http://www.ilog.com/products/jrules/documentation/jrules67/api/html/ilog/rules/studio/javascript/dom/IlrExtractorHelper.html

    ReplyDelete
  6. Hi.. Thanks a lot for responding so promptly... I did try the solution you proposed. But the build is still failing.

    C:\27_onRES_onRTS>ant -f rule-builder-script.xml BuildSomething
    Unable to locate tools.jar. Expected to find it in C:\Program Files\Java\jre1.6.
    0_04\lib\tools.jar
    Buildfile: rule-builder-script.xml

    BuildSomething:

    buildAndExtractRuleset:
    [echo] Using ECLIPSE_HOME=C:/ILOG/JRules663/eclipse
    [echo] Using ECLIPSE_HOME=C:/ILOG/JRules663/eclipse
    [echo] script.location=RulesBuild.js
    [echo] extractorName=
    [echo] workspace.dir=C:\27_onRES_onRTS\VerifyWorkspace_CVS1
    [echo] projectName=AutoApprovalRules
    [echo] archivefile=C:\rules.jar
    [java] registering script
    [java] registered script
    [java] start script
    [java] [Sat Jul 26 02:37:20 CDT 2008] RulesBuild.js STARTED
    [java] [Sat Jul 26 02:37:20 CDT 2008] JDK Compliance set to 1.5
    [java] [Sat Jul 26 02:37:20 CDT 2008] Autobuilding set to false
    [java] [Sat Jul 26 02:37:20 CDT 2008] Begin Clean...
    [java] [Sat Jul 26 02:37:21 CDT 2008] End Clean...
    [java] [Sat Jul 26 02:37:21 CDT 2008] Begin Refresh...
    [java] [Sat Jul 26 02:37:21 CDT 2008] End Refresh.
    [java] [Sat Jul 26 02:37:21 CDT 2008] Begin Full Build...
    [java] [Sat Jul 26 02:38:22 CDT 2008] End Full Build
    [java] [Sat Jul 26 02:38:22 CDT 2008] Cannot generate archive. Build failed
    or was not run.
    [java] [Sat Jul 26 02:38:22 CDT 2008] ========== AutoApprovalRules OK =====
    =====
    [java] [Sat Jul 26 02:38:22 CDT 2008] ========== AutoApprovalRulesApp OK ==
    ========
    [java] [Sat Jul 26 02:38:22 CDT 2008] ========== CommentsRules OK =========
    =
    [java] [Sat Jul 26 02:38:22 CDT 2008] ========== CommentsRulesApp OK ======
    ====
    [java] [Sat Jul 26 02:38:22 CDT 2008] ========== DOAMaxLevelRules OK ======
    ====
    [java] [Sat Jul 26 02:38:22 CDT 2008] ========== DOAMaxLevelRulesApp OK ===
    =======
    [java] [Sat Jul 26 02:38:22 CDT 2008] ========== JavaTest KO ==========
    [java] 1 22 The local variable deactivateDelegation is never read
    [java] 1 33 The local variable t1 is never read
    [java] 1 41 The local variable todayDate is never read
    [java] [Sat Jul 26 02:38:22 CDT 2008] ========== OverdueRules OK ==========

    [java] [Sat Jul 26 02:38:22 CDT 2008] ========== OverdueRulesApp OK =======
    ===
    [java] [Sat Jul 26 02:38:22 CDT 2008] ========== RoutingRules OK ==========

    [java] [Sat Jul 26 02:38:22 CDT 2008] ========== RoutingRulesApp OK =======
    ===
    [java] [Sat Jul 26 02:38:22 CDT 2008] ========== commandlinetool OK =======
    ===
    [java] [Sat Jul 26 02:38:22 CDT 2008] Workspace saved ...
    [java] [Sat Jul 26 02:38:22 CDT 2008] RulesBuild.js ENDED
    [java] script ended

    BUILD FAILED
    C:\27_onRES_onRTS\rule-builder-script.xml:13: The following error occurred while
    executing this line:
    C:\27_onRES_onRTS\rule-builder-script.xml:88: The following error occurred while
    executing this line:
    C:\27_onRES_onRTS\rule-builder-script.xml:102: Java returned: 10

    Total time: 1 minute 9 seconds

    Could you please help me with this

    ReplyDelete
  7. I dont have ILog 6.7, using 6.6.3

    Following are the parameters i am passing.

    target name="BuildSomething"
    antcall target="buildAndExtractRuleset"
    param name="projectName" value="AutoApprovalRules"
    param name="extractorName" value=""
    param name="archivefile" value="C:\rules.jar"
    param name="workspace.dir" value="C:\27_onRES_onRTS\VerifyWorkspace_CVS1"

    ReplyDelete
  8. Also made changes to use startup.jar as eclipse
    launcher (provided in jrules 663) instead of
    org.eclipse.equinox.launcher_*.jar

    ReplyDelete
  9. Sudhiranjan,
    It looks like the project JavaTest cannot be built. Maybe you can remove this project from your workspace if it is not part of the ruleset?

    All projects must have a status of OK , for a ruleset to be extracted.

    [java] [Sat Jul 26 02:38:22 CDT 2008] ========== JavaTest KO ==========
    [java] 1 22 The local variable deactivateDelegation is never read
    [java] 1 33 The local variable t1 is never read
    [java] 1 41 The local variable todayDate is never read

    ReplyDelete
  10. Hi SM,

    It is building and generating the ruleset successfully now. Thanks a lot. Using the overridden extract method, without passing the extractor did not work. So I created an extractor and passed it. It is working fine now. Thank you.

    The requirement I have is to fetch the code from cvs repository and build the project on a unix machine and generate a ruleset, ruleapp and deploy on RES. As of now, I am using the res-jar and res-deploy tasks provided by ILog to put the ruleset in a ruleapp and deploy on the RES. This part is automated. But I need to automate the build and ruleset generation part also.

    The problem is I would be directly fetching the code into a folder on the unix machine (test and prod env with no eclipse installed), and then run the automated scripts to build, jar and deploy.

    1) So is there any alternative scripts or method to do it without using eclipse

    2)Even if rule studio with eclipse is installed on the unix environments, there wouldn't be a workspace directory as such to fetch the code into and build the project right?

    3) How do you build and deploy the rule projects in your project in production

    Would really appreciate your help. Thanks again for the quick responses.

    ReplyDelete
  11. Sudhiranjan,

    (1) From what I have spoken to consultants from ILOG, there is no way to build a ruleset without eclipse installed.

    I would suggest you send out a question on the ILOG forums to see if there is a way of building without eclipse installed

    (2)You can create a workspace dynamically in the script. Pass in an empty folder as the workspace parameter and use the global variable importHelper to import the projects into your workspace.

    See the documenation here.

    3) We are still developing a process of how the ruleset will be built and deployed in production.

    ReplyDelete
  12. Hi SM or Sudhirranjan,


    1) when I ran the rule-builder-script, I was getting error "couldn't find org.eclipse.equinox.launcher_*.jar in C:\ILOG\JRules662\eclipse\plugins. I also tried with startup.jar with location C:\ILOG\JRules662\eclipse. But, getting the error that startup.jar not found.

    Am I doing anything wrong? Please help me to resolve this error.

    2) I also has the same requirement
    to fetch the code from cvs repository and build the project on windows and generate a ruleset, ruleapp and deploy on RES.

    Could you please post the scripts to automate above processes?

    Please help me...

    Thanks,
    Shan

    ReplyDelete
  13. Hi Shan,

    1. I am not sure why you're getting that error. Check out the ILOG Forum , the ILOG experts should be able to help.

    2. I do not have a script to do what you need. You should look into Ant and that should help you to write a script

    ReplyDelete
  14. Hi SM,

    Thank you for the quick response.

    1) Fixed this error with version 672. But, i can see RuleBuild.js ENDED. But, I couldn't see messages ==========
    "Project Name" OK ===== and didn't create archive file (rules.jar).

    I didn't specify extractor name (left it blank). Looks like without passing the extractor did not work.

    Can you please provide extractor code?.

    Thanks,
    Shan

    ReplyDelete
  15. Hi again Shan,

    You have to define your own extractor or you have to use the extract method in ILRExtractorHelper that doesn't take in an extractor name in as an arguement.

    ReplyDelete
  16. I removed extractor argument in below code in RulesBuild.js

    // Generate ruleset archive
    this.generate = function (archivePath,ruleprojectName) {
    .....
    .....
    extractorHelper.extract(rp,jarfile)

    I can see RuleBuild.js ENDED message. But, still I couldn't see ==========
    "Project Name" OK ===== messages and didn't create archive file (rules.jar).

    Am I doing anything wrong?

    Thanks,
    Shan

    ReplyDelete
  17. Shan, are you sure the workspace.dir you have specified is a valid eclipse workspace that contains your JRules projects?

    ReplyDelete
  18. Hi SM,

    workspace.dir is correct. I found out the problem and fixed it. Now it is working fine. I corrected extractor related code in the script.

    Thank you very much for your help in this regard.

    Thanks,
    Shan

    ReplyDelete
  19. Hi
    This script was very useful. Thank you.
    How Can we create a RuleApp from the script and deploy in bres?

    ReplyDelete
  20. I have been assigned to integrate ilog with another product. The requirement is that the BOM/XOM edits and modification can be carried out right from within the product, The product has a model and if there are changes to the model, the XOM/BOM etc should get updated automatically without the need to user opening rule studio . To you guys have any pointers on how to achieve that. Some of the ideas which i have been thinking.

    (1) The ruleapp exported from RuelStudio can be edited programatically (need to study the structure of files etc)

    (2) Running the RuleStudio in headless mode and executing some generated scripts which have the changes in BOM

    ReplyDelete
  21. Need your inputs on the above questions since I am new and there are lot of things to be thought of. Do you guys have some samples which I can reuse etc for my integration project

    ReplyDelete
  22. We have very large project, because command line build needs to build all projects and will archive same time, the build is going out of space in development box's. is there a way we can build few projects intially and few more 2nd time and archive 2nd time? 2nd time build projects have dependencies with the first time projects. Very much appreciated your response.

    ReplyDelete
  23. We have very large project, because command line build needs to build all projects and will archive same time, the build is going out of space in development box's. is there a way we can build few projects intially and few more 2nd time and archive 2nd time? 2nd time build projects have dependencies with the first time projects. Very much appreciated your response.

    ReplyDelete
  24. We have very large project, because command line build needs to build all projects and will archive same time, the build is going out of space in development box's. is there a way we can build few projects intially and few more 2nd time and archive 2nd time? 2nd time build projects have dependencies with the first time projects. Very much appreciated your response.

    ReplyDelete
  25. We have very large project, because command line build needs to build all projects and will archive same time, the build is going out of space in development box's. is there a way we can build few projects intially and few more 2nd time and archive 2nd time? 2nd time build projects have dependencies with the first time projects. Very much appreciated your response.

    ReplyDelete
  26. We have very large project, because command line build needs to build all projects and will archive same time, the build is going out of space in development box's. is there a way we can build few projects intially and few more 2nd time and archive 2nd time? 2nd time build projects have dependencies with the first time projects. Very much appreciated your response.

    ReplyDelete
  27. Hi,

    Thanks for the post.
    I am currently evaluating Drools ( version 5.3).

    Many colleagues are excited about Drools because it is an open source project.
    But I must say I can't advise it for big projects.

    It is Free and you can easily make a small rule project, which is great.
    But it has so many limitations!:
    Not a lot of documentation, still many bugs ( I have to edit the ruleflow manually and add a xml namespace every single time I edit the ruleflow !), and is definitely not user friendly when it comes to rules editing!

    Even when writing rule with a "natural language", users have to deal with java imports...
    And what about function in a rule !? Seriously ?
    Either the rule is technical or non technical.
    Any import, function, get... keyword and the business user is lost

    I really can't see business users writing a rule themselves, let alone DT or ruleflows

    The so called natural language is a kind of mapping between mvel/java instructions and sentences let s say in english.

    If I want to write
    "the age of the customer is more than {age} ", the mapping will be
    Customer( age > {age} )

    Ok, that'll work..... but what if the business user suddendly wants to write the rule "the age of the customer is less than {age} " !!!!?

    Can't do unless they edit the dsl.
    But remember they are business users and don't to deal with that kind of stuff

    For me this is the huge limit of the dsl VS the verbalization of Jrules and some others:
    you have to know exactly the rules you want to write upfront !

    I don't say this is a bad product though.
    It is free and working pretty well.
    Plus I don't have enough experience dealing with Drools to draw a thorough and final conclusion.

    However I would not advise it in case final users need to edit the rules......
    Not sure how the customer will react when they know any change in the rules would have to be done by our services.

    Any opinion on this particular subject ?

    ReplyDelete
  28. Hey SM,

    Thanks for the wonderful explaination and the script.
    I am trying exactly what you have mentioned and am using Eclipse Ganymede and it throws me this error
    org.eclipse.emf.ecore.resource.Resource$IOWrappedException: The processing instruction target matching "[xX][mM][lL]" is not allowed.

    Caused by: org.xml.sax.SAXParseException: The processing instruction target matching "[xX][mM][lL]" is not allowed.

    I have checked all my xml's and it does not have any space before that and so that should not be the issue. The script executes successfully but the rules.jar is not created at the destination folder. Any help in this matter would save me in this crunch situation. I can be reached at keto.god@gmail.com

    ReplyDelete
  29. Hi SM,

    Am able to setup the xml with required entries, but the build gets failed, due to rp.getName() returns NULL value. but still am passing valid argument to this. Not sure why the value not picking up properly.

    D:\study>ant -f rule-builder-script.xml BuildSomething
    Buildfile: D:\study\rule-builder-script.xml

    BuildSomething:

    buildAndExtractRuleset:
    [echo] Using ECLIPSE_HOME=C:/Program Files/IBM/WebSphereILOGJRules701/eclipse
    [echo] script.location=D:/study/RulesBuild.js
    [echo] extractorName=
    [echo] workspace.dir=D:/study/ILOG-AC/AC_RuleApp
    [echo] projectName=AC_RuleApp
    [echo] archivefile=D:/study/AC_RuleApp.jar
    [java] registering script
    [java] registered script
    [java] start script
    [java] [Tue Oct 01 11:54:27 IST 2013] RulesBuild.js STARTED
    [java] [Tue Oct 01 11:54:27 IST 2013] JDK Compliance set to 1.5
    [java] [Tue Oct 01 11:54:27 IST 2013] Autobuilding set to false
    [java] [Tue Oct 01 11:54:27 IST 2013] Begin Clean...
    [java] [Tue Oct 01 11:54:27 IST 2013] End Clean...
    [java] [Tue Oct 01 11:54:27 IST 2013] Begin Refresh...
    [java] [Tue Oct 01 11:54:27 IST 2013] End Refresh.
    [java] [Tue Oct 01 11:54:27 IST 2013] Begin Full Build...
    [java] [Tue Oct 01 11:54:27 IST 2013] End Full Build
    [java] [Tue Oct 01 11:54:27 IST 2013] Siraj
    [java] [Tue Oct 01 11:54:27 IST 2013] line 58
    [java] [Tue Oct 01 11:54:27 IST 2013] line 64
    [java] [Tue Oct 01 11:54:27 IST 2013] line 203
    [java] [Tue Oct 01 11:54:27 IST 2013] null
    [java] [Tue Oct 01 11:54:27 IST 2013] line 210
    [java] [Tue Oct 01 11:54:27 IST 2013] Cannot call method "getName" of null
    [java] [Tue Oct 01 11:54:27 IST 2013] RulesBuild.js ENDED
    [java] script ended

    BUILD SUCCESSFUL
    Total time: 14 seconds
    many thanks!!
    Siraj

    ReplyDelete
  30. Hi, I went through your code and adapted it according to my needs.

    We are using WODOM 8.5 and the given JavaScript solution fails at multiple points.

    We use RES - Rules Execution Server where in we manually checkout the RuleApp's. I've been trying multiple approaches but when the RuleApp archive is generated the validation fails.

    The option we have been trying for quite sometime now is of 'Adv Automation using JavaScript'

    When i run your code after making changes.. these are the type of errors that i came across... can anyone throw some light on how do i got about executing them?

    The errors:

    [java] !MESSAGE An error occurred while automatically activating bundle org.eclipse.ui.workbench (686).
    [java] !STACK 0
    [java] org.osgi.framework.BundleException: The activator org.eclipse.ui.internal.WorkbenchPlugin for bundle org.eclipse.ui.workbench is invalid

    [java] Caused by: java.lang.NoClassDefFoundError: org.eclipse.swt.SWTError
    [java] Caused by: java.lang.ClassNotFoundException: org.eclipse.swt.SWTError

    [java] Caused by: java.lang.NoClassDefFoundError: org.eclipse.ui.plugin.AbstractUIPlugin

    [java] Caused by: org.eclipse.core.runtime.internal.adaptor.EclipseLazyStarter$TerminatingClassNotFoundException: An error occurred while automatically activating bundle org.eclipse.ui.workbench (686).

    [java] Caused by: org.osgi.framework.BundleException: The activator org.eclipse.ui.internal.WorkbenchPlugin for bundle org.eclipse.ui.workbench is invalid



    Also, can someone help me understand the detailed concept of 'extractors'



    ReplyDelete