I'm trying to find an appropriate solution/framework to centralize and maintain rules. The number of rules is huge and they change frequently. I've gone through rules engines like Drools but find them unsuitable for reasons like the complexity of rules execution which affects maintainability and rules centralization overheads (rules engines often require another repository system to hold the rules).
The solution/framework I'm looking for should ideally allow me to write rules in standard programming languages such as Java with little overheads to centralizing and maintaining rules.
Big thanks in advance.
Drools 5.2.0 will have the new parser API, which - in theory - allows you to avoid DRL and write a rule engine's Left Hand Side (LHS) in Java, much like you'd write a JPA query with the JPA 2.0 criteria API.
Have you tried Spring support for dynamic languages? You can invoke beans written in languages like Groovy or JRuby (I wrote JavaScript support some time ago if you care). Source code of these dynamic beans can be extracted into separate files which are scanned periodically to discover changes at runtime.
Much simpler, yet still powerful.
Related
I just got introduced to Business Rules, .drl files, Rule Engines and Drools.While exploring I realized that all those conditions and fact checking can be done in Java programs as well then why do we need to write .drl files and have a Rule Engine separately.
Examples I'hv found on internet does not distinguish between why we should a write a .drl file for a partucular Business Logic rather than putting the logic in a Java Class.
An explanation using an example would be a great help.
The commonly cited advantages of using a rule engine include:
Declarative business rules: using a DSL which business analysts (rather than developers) can use to define business rules allows an approach like ‘let your developers do the coding while your business analysts manage the business rules’.
Externalising the rules: this may (depending on the chosen rules engine) allow you to change those rules without rebuilding and redeploying your entire application.
Non functionals: a dedicated rules engine may perform better (through concurrent execution, for example) than a series of if/then/else clauses buried in your code and similarly a dedicated rules engine may provide better diagnostics and visibility of rule decisions than a roll-your-own solution. Of course, these are not necessarily true however it is true to say that if a roll-your-own solution is to match or exceed a well used rules engine in this regard then it would take some non trivial development to do so.
(There are others but for the purpose of this answer I think the above suffice).
Of course, these advantages have more or less weight depending on the specifics of each case. So, for example, if the proposed business rules are very simple, are small in number, are unlikely to change and if there are relaxed expectations as to their execution time then many of the above advantages do not apply.
However, plenty of implementations started out small, simple and with an expectation of few changes in future only for all of those expectations to be challenged by reality :)
It's also worth nothing that to some extent you can use Drools and "put ... the logic in a Java Class" by using Drool's Java dialect.
If you are being encouraged to use Drools against your wishes then perhaps a compromise solution would be to wrap an interface around your rules implementation and start with a simple implementation of that interface allowing for the possibility of a Drools based implementation later if/when a compelling case can be made for it.
The idea is:
To not mix up business rules with application logic
To have .drl files separate from the application, so they can be updated separately.
Ideally, although I doubt this is ever realized in practice, the business subject matter experts could write the business rules themselves.
I'm interested in metaprogramming (i.e. programs that help programmers do tedious programming tasks). I'm looking for a tool which has the following properties:
usable both at compile time and runtime;
inspects program structure;
can add new classes, methods or fields and make them visible to Java compiler;
can change behavior of methods;
Java-based (well, Java is most popular programming language according to some rankings);
good integration with IDEs and build tools like Ant, Gradle or Maven;
actively maintained project;
easy to use and extend;
There are some solutions for this, like:
reflection
AspectJ
Annotation Processing Tool
bytecode manipulation (CGLIB, Javassist, java.lang.instrument)
Eclipse JDT
Project Lombok
Groovy, JRuby, Scala
But unfortunately none of them meets all the criteria above. Is there any complete metaprogramming solution for Java?
There's JackPot, which is Java based but I don't think gets a lot a current attention. Has ASTs and symbol tables AFAIK. You can probably extend it; I doubt anybody will stop (or help) you.
There's the Java-based compiler APIs for the Sun, er, Oracle java compiler. They're likely actively maintained, but I don't think you can modify source code and regenerate it. Certainly has symbol tables; dunno about trees. Probably pretty hard to extend; you have to keep up with the compiler guys, not the other way round.
There is ANTLR, which has a Java implementation and a Java parser that will build ASTs. I don't think it has full symbol tables, so doing serious code analysis/revision is likely to be hard. ANTLR is certainly actively maintained, and nobody will object to you enhancing the Java grammar with symbol tables. Just know that will take you about 6 months for Java 1.6 if that's all you do. (That's how long it took our internal [smart] guy to do it for DMS, starting with symbol table support for 1.4).
Not in Java, and not easily integrated into IDEs, but capable of carrying massive analysis and transformation on Java code is our DMS Software Reengineering Toolkit with its Java Front End.
DMS is generic compiler machinery: parsing, AST building, symbol table machinery, flow analysis machinery, with that additional bonuses of source-to-source transformations and generic prettyprinting of ASTs back to legal text including retention of comments. It offers a set of APIs supporting these services, and additional tools for defining grammars and langauge-dependent flow analyzers.
The Java Front End gives crucial detail (using those APIs) to DMS to allow it process Java: a grammar/parser, full symbol table construction for Java 1.4-1.6 (with 1.7 due momentarily), as well as some control and data flow analysis (to be extended over time because this stuff is so useful).
By using the services provided by DMS and the Java Front end, one can reasonably contemplate building arbitrary Java anlaysis and transformation tools. (This makes the tool a "complete" metaprogramming tool, in that it can inspect any language structure, or change any language structure, as opposed to say template metaprogramming or reflection). We believe this to be much more effective than ad hoc tools because you don't have to build the infrastructure, the infrastructure provided is robust and handles cases you don't have the energy to implement, and it is designed to support such tasks. YMMV.
DMS/Java Front end have been used to construct a variety of Java tools: test coverage, profilers, dead code elimination, clone detection on scale, JavaDoc with hyperlinked source-code, fast XML parser/generators, etc.
Yes, its actively maintained; undergoing continuous enhancement since the first version in 1998.
There's a Java metaprogramming framework that is part of Tapestry IOC, it's called Plastic. It munges class bytecodes using custom classloaders, I haven't tried it yet but it looks like it gives a simple interface that still enables the programmer to make powerful metaprogramming changes.
Check out the Meta Programming System:
http://www.jetbrains.com/mps/
It has great IDE support and is used quite frequently by the smart folks at JetBrains.
Check out Spring Roo.
How would you develop a game that could end up with complex rules but you need to work on the rules (add, tweak, balance) a lot? I have looked at rule-based languages but I haven't found quite useful enough information regarding this.
UI etc. will be developed later, first I'd need to iteratively develop the rules and formulas and test them out between iterations. The game in question would be a tactical two-player game where players select "troops" and a large part of the game is choosing the correct troop setup. So the rules could be something like
If attacker's skill A is greater than defenders skill B and defender does not have extra skill Z then ...
That's obviously a very simple rule, I expect there to be dozens, if not hundreds of rules, with paths (if A then if B....).
For testing I would write a test framework that can run the rule sets through with large number of iterations and logging that allows me to see how the latest changes affected balance. It would also be useful to be able to define acceptable values and a possibility to see easily the changes. What tools are there for this?
The language of choice is either Python or Java (depending on whether I want to target Android or not - probably I will).
Whatever you'll do, in this sort of program you'll end up implementing half of Prolog anyway. Check out the forward-chaining, backward-chaining, and backtracking algorithms.
A pure-Java version of Prolog called Jekejeke was recently released. I can't comment on its quality.
Python makes it much easier than Java to implement backtracking using generators and yield statements.
As with larsmans I'm going to suggest that you use Prolog for your rules development. It's just the best language in semi-common use for doing exactly the kind of thing you want to do. I will, however, instead recommand tuProlog as looking like the ideal environment for your needs given that you want to write the game in Java. TuProlog is intended as an embeddable Prolog environment (can be embedded in Java or in .NET) with very finely-tuned library inclusion so you don't have to carry around a whole, bloated Prolog world with you when you're using just small parts of it.
Here's the blurb from the web site:
tuProlog is a light-weight Prolog system for distributed applications and infrastructures, intentionally designed around a minimal core (containing only the most essential properties of a Prolog engine), to be later configured by (statically and dynamically) loading/unloading libraries of predicates. tuProlog also natively supports multi-paradigm programming, providing a clean, seamless integration model between Prolog and mainstream object-oriented languages -- namely Java, for tuProlog Java version, and any .NET-based language (C#, F#..), for tuProlog .NET version. It is also easily deployable, just requiring the presence of a Java/CLR virtual machine and an invocation upon a single self-contained archive file. Interoperability is further developed along the two main lines of Internet standard patterns and coordination models.
It's an interesting question, though a bit broad and generic. I'll try to answer it according to my interpretation of what you're asking ;)
Your main concern seems to be about being able to express the rules in a concise, readable way that would allow you to always keep the definition clear and change it rapidly. Since you say the rules are probably going to get complex, I believe your best bet would be to write a DSL for them.
Try to writing a grammar that would be sufficient for describing your rules and then see how to plug it into your game. ANTLR could be very helpful there, especially because it supports both Java and Python.
try The A.I. of F.E.A.R.. there FSM (finite state machine) was combined with A* pathfinding. instead of finding a path in a terrain the engine found chains of goals to implement generation of "intelligent" behaviour of agents on the fly. maybe there is something inspiring in there for you.
Is it possible to replace any java coding which I use daily with groovy or scala? E.g. writing small webapps which include servlets/portlets etc.
I've completely replaced my server side processing/data crunching that would previously be written in Java with Scala. It's made life a lot easier, and a lot more fun.
Small servlets for REST webservices written on top of Step (web pico "framework", it's a single code file, comically small servlet wrapper) http://github.com/alandipert/step. Scala's xml handling combined with a simple json outputter (I use Twitter's) makes this completely painless.
Hibernate + Annotations as my persistence layer (very painless once you've cleaned up the Hibernate's collection handling/types)
Various data crunching background tasks.
It's certainly possible, and a really simple transition to make. Just start writing Scala as if you were writing Java, at it's worst it's just Java but much less verbose. From there you can gradually pick up the Scala concepts over time: Options, functional concepts, closures etc.
I have been using Groovy for a few months now and find that it addresses a lot of the things that have been bothering me about Java for a number of years (handling collections, null pointers, verbosity). The principal is that you should be able to take your Java source file, rename it to .groovy and start converting gradually ... that isn't quite true because Groovy doesn't support inner classes, for loops with multiple loop variables, do..while, and character literals, but these are easy to fix.
Scala is the statically-typed alternative ... Bill Venners reckons it allows you to achieve the same as Java (with compile-time checking) in about half the number of lines of code. And Scala has the LIFT framework, which is less mature than Grails but still promising.
Both Groovy and Scala are worth exploring, and will (eventually) make you more productive.
I use Groovy all the time for utilities, both on the command line and on the web. Often, the utilities use jars/class files from my project, since it is all on the JVM.
For web utils, take a look at Groovlets. You can come up to speed with Groovlets in a couple of hours. A groovlet is simply a servlet distilled down to its essence.
If you need to persist state, Grails is a leading web framework (with a higher learning curve).
I don't know about portlets per se, as that is its own beast.
yes. both are compiled for the same VM, you can use Java classes in them. the programming language syntax is just sugar coating on the JVM bytecode, which is the same no matter what.
I want to move a legacy Java web application (J2EE) to a scripting language - any scripting language - in order to improve programming efficiency.
What is the easiest way to do this? Are there any automated tools that can convert the bulk of the business logic?
Here's what you have to do.
First, be sure you can walk before you run. Build something simple, possibly tangentially related to your main project.
DO NOT build a piece of the final project and hope it will "evolve" into the final project. This never works out well. Why? You'll make dumb mistakes. But you can't delete or rework them because you're supposed to evolve that mistake into the final project.
Next, pick a a framework. What? Second? Yes. Second. Until you actually do something with some scripting languages and frameworks, you have no real useful concept of what you're doing. Once you've built something, you now have an informed opinion.
"Wait," you say. "To do step 1 I had to pick a framework." True. Step 1, however, contains decisions you're allowed to revoke. Pick the wrong framework for step 1 has no long-term bad effects. It was just learning.
Third, with your strategic framework, and some experience, break down your existing site into pieces you can build with your new framework. Prioritize those pieces from most important to least important.
DO NOT plan the entire conversion as one massive project. It never works. It makes a big job more complex than necessary.
We'll use Django as the example framework. You'll have templates, view functions, model definitions, URL mapping and other details.
For each build, do the following:
Convert your existing model to a Django model. This won't ever fit your legacy SQL. You'll have to rethink your model, fix old mistakes, correct old bugs that you've always wanted to correct.
Write unit tests.
Build a conversion utility to export old data and import into the new model.
Build Django admin pages to touch and feel the new data.
Pick representative pages and rework them into the appropriate templates. You might make use of some legacy JSP pages. However, don't waste too much time with this. Use the HTML to create Django templates.
Plan your URL's and view functions. Sometimes, these view functions will leverage legacy action classes. Don't "convert". Rewrite from scratch. Use your new language and framework.
The only thing that's worth preserving is the data and the operational concept. Don't try to preserve or convert the code. It's misleading. You might convert unittests from JUnit to Python unittest.
I gave this advice a few months ago. I had to do some coaching and review during the processing. The revised site is up and running. No conversion from the old technology; they did the suggested rewrite from scratch. Developer happy. Site works well.
If you already have a large amount of business logic implemented in Java, then I see two possibilities for you.
The first is to use a high level language that runs within the JVM and has a web framework, such as Groovy/Grails or JRuby and Rails. This allows you to directly leverage all of the business logic you've implemented in Java without having to re-architect the entire site. You should be able to take advantage of the framework's improved productivity with respect to the web development and still leverage your existing business logic.
An alternative approach is to turn your business logic layer into a set of services available over a standard RPC mechanisim - REST, SOAP, XML-RPC or some other simple XML (YAML or JSON) over HTTP protocol (see also DWR) so that the front end can make these RPC calls to your business logic.
The first approach, using a high level language on the JVM is probably less re-architecture than the second.
If your goal is a complete migration off of Java, then either of these approaches allow you to do so in smaller steps - you may find that this kind of hybrid is better than whole sale deprecation - the JVM has a lot of libraries and integrates well into a lot of other systems.
Using an automated tool to "port" the web application will almost certainly guarantee that future programming efficiency will be minimised -- not improved.
A good scripting language can help programming efficiency when used by good programmers who understand good coding practices in that language. Automated tools are usually not designed to output code that is elegent or well-written, only code that works.
You'll only get an improvement in programming efficiency after you've put in the effort to re-implement the web app -- which, due to the time required for the reimplementation, may or may not result in an improvement overall.
A lot of the recommendations being given here are assuming you -- and just you -- are doing a full rewrite of the application. This is probably not the case, and it changes the answer quite a bit
If you've already got J2EE kicking around, the correct answer is Grails. It simply is: you probably already have Hibernate and Spring kicking around, and you're going to want the ability to flip back and forth between your old code and your new with a minimum amount of pain. That's exactly Groovy's forte, and it is even smoother than JRuby in this regards.
Also, if you've already got a J2EE app kicking around, you've already got Java developers kicking around. In that case, learning Groovy is like falling off a ladder -- literally. With the exception of anonymous inner classes, Groovy is a pure superset of Java, which means that you can write Java code, call it Groovy, and be done with it. As you become increasingly comfortable with the nicities of Groovy, you can integrate them into your Java-ish Groovy code. Before too long, you'll be writing very Groovy code, and not even really have realized the transition.