Debugging Drools inside an EJB in eclipse - eclipse

I am currently debugging a web application which uses a drools ruleset inside an EJB to process business rules. It's deployed inside a JBoss server. I've configured eclipse to run the server so I could use Debug on Server functionality of eclipse.
When I reach the class that fires the drools ruleset, the server loses focus and returns after all the rules are fired. Is there a way where I could trace what rules are being fired? Right now, what I do is put logs inside the *.drl files so I know where the application is inside the rules engine.

you can get the generated java source code of any rule when you add a file with name drools.packagebuilder.conf to your %USERHOME% directory.
The file must contain the following instruction:
drools.dump.dir = d:/myDroolsJavaSourceCode
The directory d:/myDroolsJavaSourceCode - Directory (or any other given name) must exist otherwise the Drools Packagebuild will stop execution.
Then you can add this directory to your Eclipse Environment as new project (probably you have to remove the flag 'Default Location' to choose the 'myDroolJavaSourceCode').
Then you can open the file in Eclipse and set break points in the editor.
May be you must attach the directory also during debugging execution twice.
Best regards!
Christof

As far as I know you can't debug drl file. What we did was to encapsulate the logic of when and then in a method, so that you can at least debug that.
Maddy

What I did is I downloaded the sources for drools-engine and compiled the drl files to their java sources. When you run the app, you'll have an option to attach sources when the break point reaches the engine. It's still hard to trace the rules that are fired (multiple rules from different drls can be fired) but it's better than just sysout logging.

Related

How can I let Tomcat run a command after it finishes deploying web application's .war files

We know that during Tomcat startup, it will deploy the .war files of its web applications. My question is after the deployment I need to run a command to modify a file inside WEB-INF/ of the web application which is generated after deployment, and I need to let Tomcat do this automatically for me, is this possible to achieve ? Something like post_run command after deployment.
I found that CustomEventHookListener can probably do this How to run script on Tomcat startup?, but this involves in making a new Java class, and I'm not allowed to do so. I have to figure out way to modify the existing Tomcat configs like server.xml or tomcat.conf in TOMCAT_HOME/conf to do so.
The main issue about not using a Event Hook Listener is that there's no reliable way to tell if the application is ready or not, as Catalina implements it's own lifecycle for each of their components (as seen in https://tomcat.apache.org/tomcat-8.5-doc/api/org/apache/catalina/Lifecycle.html).
Your best shot is to use tail or some external program infer the component's state, but AFAIK there's no way to implement listeners directly in the configuration files.

Convenient way to run eclipse plugin

I have recently started developing an Eclipse plugin (which is basic stuff for now) and I am struggling with "default" way to run Eclipse plugin ("Run as Eclipse application").
The Eclipse is starting another instance with my plugin already installed in it (this is default behaviour).
The problem is that when I want to re-run my plugin project and I press "run" button again (or Ctrl + F11) (and the another Eclipse instance still running) I get following message:
"Could not launch the application because the associated workspace is currently in use by another Eclipse application".
The error makes sense, and when I close "testing" Eclipse instance I am able to run my plugin again.
The question is - "is it normal routine for plugin development?". Maybe I am missing something, e.g. special arguments for Eclipse?
This seems all pretty normal. The error message is since the run configuration is specifing a workspace and when you start a second instance using the same workspace it is locked and considered in use.
What I usually do when testing a plugin is to create a run configuration (click "Run...") where I disable all the plugins I wont need when testing. This makes sure that the test starts up a couple of seconds quicker. Make sure you save that run configuration as a *.launch file aswell, that makes it quicker to test the next time. Or it can be used to share the configuration.
There's a lot you can configure in the run configuration, such as eclipse arguments, vm argument, if you want environment variables set, etc. So be sure to experiment a little.
In your run configuration. Main tab->Workspace Data ->Location text box add this:
${workspace_loc}/../runtime-EclipseApplication${current_date:yyyyMMdd_HHmmss}
Note the suffix ${current_date:yyyyMMdd_HHmmss} by this every time you launch your application new workspace will be created. So you will not get any error message saying workspace is locked.
But be careful as the folder .metadata will be different for different instances as their work-spaces are different. Thus preferences stored/retrieved by different instances are NOT in sync.
You are probably missing one important point: Eclipse supports the Java hot code replacement. Therefore in many cases you can modify your Java code while your application Eclipse instance is running, save the code and continue without restarting.
If hot code replacement is not possible, Eclipse will tell you, so you always know whether the editing changes are applied to the running instance.
This works best with more recent versions of the JVM, so consider upgrading to the latest Java 7 version, even if you write code to be compliant with Java 1.5 or 6.

tomcat6 and drool rules reloading

I have run into an issue where when I modify my drools rules(.drl) on the fileSystem it appears to work as a JUnit testcase but fails when try to test the same in the web application running under Tomcat6.
When I modify the drl file under Tomcat, I do see logs saying KnowledgeAgent is rebuilding the knowledgeBase and so on and I do see new a instance of KBase under KAgent in the debugger but still when I execute the rule it shows the original values.
Was wondering if there is any cache tomcat uses internally for rules and if yes whats the workaround?
Any help is appreciated.
As I understand your question, I think you have to reload your drl file when it gets changed.
Are you using ResourceFactory.newClassPathResource() method for loading your rule files? If yes, then use ResourceFactory.newInputStreamResource(stream) method. It always gets latest modified drl file.

Why does tomcat replace context.xml on redeploy?

Documentation says if you have a context file here:
$CATALINA_HOME/conf/Catalina/localhost/myapp.xml
it will NOT be replaced by a context file here:
mywebapp.war/META-INF/context.xml
It is written here: http://tomcat.apache.org/tomcat-6.0-doc/config/context.html
Only if a context file does not exist for the application in the $CATALINA_BASE/conf/[enginename]/[hostname]/, in an individual file at /META-INF/context.xml inside the application files.
But everytime I re-deploy the war it replaces this myapp.xml with the /META-INF/context.xml!
Why does it do it and how can I avoid it?
Thanx
Undeploy part of redeploy deletes app and the associated context.xml.
If you use maven tomcat plugin you can avoid deleting context.xml if you deploy your app with command like this:
mvn tomcat:deploy-only -Dmaven.tomcat.update=true
More info here: https://tomcat.apache.org/maven-plugin-2.0-beta-1/tomcat7-maven-plugin/deploy-only-mojo.html
You can use deploy-only with parameter mode to deploy the context.xml too.
The short answer:
Just make the TOMCATHOME/conf/Catalina/localhost dir read-only, and keep reading for more details:
For quick deployment mode (Eclipse dynamic web project, direct Tomcat
connection, etc.) on a local/non-shared Tomcat server you can just define your JDBC datasource (or any
other 'web resource') using the META-INF/context.xml file inside the
WAR file. Easy and fast in your local environment, but not suitable for staging, QA, or
production.
For build deployment mode (usually for staging, QA, or prod), JDBC
datasources and other 'web resources' details are defined by the
QA/production team, not the development team anymore. Therefore, they
must be specified in the Tomcat server, not inside the WAR file
anymore. In this case, specify them in the file
TOMCATHOME/conf/Catalina/localhost/CONTEXT.xml (change Catalina
by the engine, and localhost by the host, and CONTEXT by your context accordingly). However,
Tomcat will delete this file on each deployment. To prevent this
deletion, just make this dir read-only; in Linux you can type:
chmod a-w TOMCATHOME/conf/Catalina/localhost
Voila! Your welcome.
The long answer
For historical reasons Tomcat allows you to define web resources (JDBC datasources, and others) in four
different places (read four different files) in a very specific order of precedence, if you happen to define the same resource multiple times. The ones named in the
short answer above are the more suitable nowadays for each purpose, though you could still
use the others (nah... you probably don't want to). I'm not going to
discuss the other ones here unless someone asks for it.
On tomcat7, also woth autoDeploy=false the file will be deleted on undeploy. This is documented and not a bug (althought it avoids good automated deployments with server-side fixed configuration).
I found a workaround which solved the problem for me:
create a META-INF/context.xml file in your webapp that contains
on the Server create a second context "/config-context" in server.xml and put all your server-side configuration parameters there
on the application use context.getContext("/config-context").getInitParameter(...) to access the configuration there.
This allows a per-host configuration that is independent of the deployed war.
It should also be possible to add per-context configurations by adding contexts like "/config-context-MYPATH". In your app you can use the context path oth the app to calculate the context path of the config app.
According to the documentation (http://tomcat.apache.org/tomcat-8.0-doc/config/automatic-deployment.html#Deleted_files) upon redeploy tomcat detects the deletion (undeploy) of your application. So it will start a cleanup process deleting the directory and xml also. This is independent of auto deployment - so it will happen upon redeployment through manager and modification of war also. There are 3 exceptions:
global resources are never deleted
external resources are never deleted
if the WAR or DIR has been modified then the XML file is only deleted
if copyXML is true and deployXML is true
I don't know why, but copyXML="false" deployXML="false" won't help.
Secondly: Making the directory read only just makes tomcat throwing an exception and won't start.
You can try merging your $CATALINA_BASE/conf/Catalina/localhost/myapp-1.xml, $CATALINA_BASE/conf/Catalina/localhost/myapp-2.xml, etc files into $CATALINA_BASE/conf/context.xml (that works only if you make sure your application won't deploy its own context configuration, like myapp-1.xml)
If someone could tell what is that "external resources" that would generally solve the problem.
The general issue as described by the title is covered by Re-deploy from war without deleting context which is still an open issue at this time.
There is an acknowledged distinction between re-deploy which does not delete the context, and deploy after un-deploy where the un-deploy deletes the context. The documentation was out of date, and the manager GUI still does not support re-deploy.
Redeployment means two parts: undeployment and deployment.
Undeployment removes the conf/Catalina/yourhost/yourapp.xml because the
<Host name="localhost" appBase="webapps" unpackWARs="true"
autoDeploy="true"> <!-- means autoUndeploy too!!! -->
</Host>
Change the autoDeploy="false" and Tomcat has no order anymore to remove the conf/Catalina/yourhost/yourapp.xml.
There is an feature that allowes us to make those steps (undeploy/deploy) as one single step (redeploy) that do not remove the context.xml. This feature is available via the manager-text-interface, but the option is not available using the manager-html-interface. You might have to wait until the bug in tomcat is fixed. You can use the method described in this answer as an workaround.

How does ‘Servers’ view work underlying in Eclipse?

‘Servers’ is built-in view in Eclipse. We could integrate Java EE server into Eclipse easily. It could start/stop server both in normal and debug modes. Moreover, we could even set timeout and deployment path, things like that. Various types of server tomcat, jboss, websphere are supported, no intrusive to server.
I am just curious about how these cool things happen behind the scene. The complete mechanism is large and complex, so I just want to know general mechanism about it, an article also could be fine for me. Thank you!
It's the server-specific plugin which does all the work. When integrating a Server in Eclipse you basically need to instruct the plugin where to find the installation root of the server in question. The plugin in turn knows precisely where to locate the default libraries, how to deploy webapps to the server in question and how to start/stop the server with eventually extra commandline arguments.
Since every server make/version needs a different approach (as different as when you need to do it "manually"), I'll only give a Tomcat 6.0 based example how it roughly works. Doubleclick the server entry in Servers view and check the Server Location section. The field Server Path denotes the root location of configuration files. It's by default in Eclipse metadata (when Use workspace metadata is selected). If you browse further in this folder, you'll find something like tmp0\conf\server.xml. It contains information about where the to-be-deployed webapps are located, which context name it should have and so on. The plugin basically gives this information to Tomcat and it will handle it further.
Basically, server adapters are Eclipse plugins and allow to extend the IDE by implementing a set of generic actions (start, debug, stop, deploy, undeploy) that are translated into server specific orders. They also expose server specific configuration parameters. The deployment is more or less intrusive depending on the server (it may be done outside the server folder tree or in a special eclipse folder).