<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-3925928603549971013</id><updated>2012-02-17T05:12:24.637+01:00</updated><category term='jBPM'/><category term='JBoss'/><category term='Security'/><category term='Java'/><title type='text'>Maurice de Chateau</title><subtitle type='html'>Yet another software enthusiast's brain dump</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://mauricedechateau.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3925928603549971013/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://mauricedechateau.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Maurice de Chateau</name><uri>https://profiles.google.com/111735333878743353142</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-srAZJqeqcc4/AAAAAAAAAAI/AAAAAAAAAE8/GRJGUoLka70/s512-c/photo.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>13</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-3925928603549971013.post-1828735093187474152</id><published>2011-08-16T09:37:00.000+02:00</published><updated>2011-12-10T09:54:24.748+01:00</updated><title type='text'>Update on the Quartz caveat</title><content type='html'>My &lt;a href="http://mauricedechateau.blogspot.com/2011/07/external-quartz-on-jboss-51.html"&gt;previous post&lt;/a&gt; explained how to use Quartz on JBoss 5.1, and gave you a heads-up about the way JBoss properties are mangled on Windows platforms.&lt;br /&gt;&lt;br /&gt;Kudos to the guys at Terracotta, who picked up quickly on &lt;a href="https://jira.terracotta.org/jira/browse/QTZ-199"&gt;the corresponding issue I filed&lt;/a&gt; and included a fix in the very next release (which is 2.1, released September 16th)!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3925928603549971013-1828735093187474152?l=mauricedechateau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mauricedechateau.blogspot.com/feeds/1828735093187474152/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://mauricedechateau.blogspot.com/2011/08/update-on-quartz-caveat.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3925928603549971013/posts/default/1828735093187474152'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3925928603549971013/posts/default/1828735093187474152'/><link rel='alternate' type='text/html' href='http://mauricedechateau.blogspot.com/2011/08/update-on-quartz-caveat.html' title='Update on the Quartz caveat'/><author><name>Maurice de Chateau</name><uri>https://profiles.google.com/111735333878743353142</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-srAZJqeqcc4/AAAAAAAAAAI/AAAAAAAAAE8/GRJGUoLka70/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3925928603549971013.post-6419229388574853802</id><published>2011-07-18T10:43:00.004+02:00</published><updated>2011-12-10T09:54:53.495+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JBoss'/><title type='text'>'External' Quartz on JBoss 5.1</title><content type='html'>On our current project, we have the requirement to be able to run our application on more than JBoss AS alone. When confronted with the need to schedule certain tasks, we considered a few options:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Use EJB timers: Due to the nature of the tasks (e.g. interdependencies) this mechanism is not suitable - it's simply just not sophisticated enough.&lt;/li&gt;&lt;li&gt;Use the Quartz functionality provided along with the JBoss distribution: While this may do exactly what we need, it wouldn't be portable to app servers from other vendors.&lt;/li&gt;&lt;/ul&gt;So the decision was made to use Quartz, not as readily available from JBoss but as an add-on library ('external', if you&amp;nbsp;will). I found a couple of articles that pointed me in the right direction:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.len.ro/2008/10/another-way-to-use-quartz-in-jboss/"&gt;"Another way to use Quartz in JBoss"&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.mastertheboss.com/jboss-application-server/84-jboss-quartz.html?showall=1"&gt;"JBoss Quartz tutorial"&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://adventuresofajavadeveloper.blogspot.com/2011/03/scheduling-job-using-jboss-510ga-and.html"&gt;"Scheduling a job using Jboss-5.1.0.GA and Quartz"&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;We used Quartz version 2.0.2 - the latest and greatest at the time I write this - and since Maven is our build tool of choice, the following dependency pulls all required libs into our project:&lt;br /&gt;&lt;pre class="brush:xml"&gt;&lt;dependency&gt;&lt;br /&gt;  &lt;groupid&gt;org.quartz-scheduler&lt;/groupId&gt;&lt;br /&gt;  &lt;artifactid&gt;quartz-jboss&lt;/artifactId&gt;&lt;br /&gt;  &lt;version&gt;2.0.2&lt;/version&gt;&lt;br /&gt;  &lt;scope&gt;provided&lt;/scope&gt;&lt;br /&gt; &lt;/dependency&gt;&lt;br /&gt;&lt;/pre&gt;We use provided scope here since we won't be including Quartz in our project's deliverables; instead we put such dependencies on our server explicitly. Either approach would work, though.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;1) Clean up your installation.&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;So, the first job at hand is to remove the Quartz artifacts from our JBoss installation. I guess it makes sense to prevent different versions from showing up in your classpath. The files to be removed are:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;${jboss.home.dir}/common/lib/quartz.jar&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;${jboss.home.dir}/server/[SERVER_NAME]/deploy/quartz-ra.rar&lt;/span&gt; (in EAP this is an exploded RAR, so remove the directory)&lt;/li&gt;&lt;/ul&gt;Before deleting anything from the &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;common/lib&lt;/span&gt; directory, be sure that there aren't any other servers running from the same AS installation that need that file!&lt;br /&gt;&lt;br /&gt;&lt;b&gt;2) Add the required Quartz libraries to you server.&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;The following file should be in place after this step:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;${jboss.home.dir}/server/[SERVER_NAME]/lib/quartz-all-2.0.2.jar&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;That's right. Just one jar, very convenient - and the added bonus is that this already contains the stuff that's needed for deployment in other app servers, so no need to have different dependencies in different deployments.&lt;br /&gt;&lt;br /&gt;Note that this file is not downloaded if you include the dependencies through Maven as indicated above, you have to download the &lt;a href="http://www.quartz-scheduler.org/download/download-catalog.html"&gt;full distribution&lt;/a&gt; to get it.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;3) Add an MBean to the JBoss configuration.&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;The following is a simple example of a Quartz MBean configuration:&lt;br /&gt;&lt;pre class="brush:xml"&gt;&lt;server&gt;&lt;br /&gt;  &lt;mbean code="org.quartz.ee.jmx.jboss.QuartzService" name="user:service=QuartzService,name=QuartzService"&gt;&lt;br /&gt;   &lt;attribute name="JndiName"&gt;Quartz&lt;/attribute&gt;&lt;br /&gt;   &lt;attribute name="Properties"&gt;&lt;br /&gt;    org.quartz.scheduler.instanceName = DefaultQuartzScheduler&lt;br /&gt;    org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool&lt;br /&gt;    org.quartz.threadPool.threadCount = 5&lt;br /&gt;    org.quartz.threadPool.threadPriority = 4&lt;br /&gt;    org.quartz.jobStore.class = org.quartz.simpl.RAMJobStore&lt;br /&gt;   &lt;/attribute&gt;&lt;br /&gt;  &lt;/mbean&gt;&lt;br /&gt; &lt;/server&gt;&lt;br /&gt;&lt;/pre&gt;If you use this, no extra DataSource needs to be configured and Quartz keeps its jobs in memory. For more specifics on the configuration possibilities (there are a lot!), see &lt;a href="http://www.quartz-scheduler.org/docs/configuration/"&gt;http://www.quartz-scheduler.org/docs/configuration/&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Put the XML above in a x-service.xml file in your server's deploy dir, like e.g.:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;${jboss.home.dir}/server/[SERVER_NAME]/deploy/quartz-service.xml&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;b&gt;4) Point Quartz at the jobs you want done.&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Obviously it now is possible to use Quartz from code inside deployed applications. Just retrieve the scheduler from JNDI like so:&lt;br /&gt;&lt;pre class="brush:java"&gt;InitialContext ctx = new InitialContext();&lt;br /&gt; Scheduler scheduler = (Scheduler) ctx.lookup("Quartz");&lt;br /&gt;&lt;/pre&gt;But for our purpose this just isn't good enough, we want to be able to schedule tasks from configuration files. To accomplish that, we need to perform a number of steps:&lt;br /&gt;&lt;br /&gt;&lt;b&gt;a)&lt;/b&gt; Enable the Quartz plugin that reads jobs and triggers from an indicated XML file. This is done by adding the following&amp;nbsp;properties to the configuration shown in step 3):&lt;br /&gt;&lt;pre class="brush:xml"&gt;org.quartz.plugin.jobInitializer.class = org.quartz.plugins.xml.XMLSchedulingDataProcessorPlugin&lt;br /&gt;   org.quartz.plugin.jobInitializer.fileNames = ${jboss.server.home.dir}/conf/quartz-jobs.xml&lt;br /&gt;   org.quartz.plugin.jobInitializer.scanInterval = 120&lt;br /&gt;&lt;/pre&gt;For details on this plugin see &lt;a href="http://www.quartz-scheduler.org/api/2.0.0/org/quartz/plugins/xml/XMLSchedulingDataProcessorPlugin.html"&gt;http://www.quartz-scheduler.org/api/2.0.0/org/quartz/plugins/xml/XMLSchedulingDataProcessorPlugin.html&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;b)&lt;/b&gt; Create a class that implements the &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;org.quartz.Job&lt;/span&gt; interface for each such a task. This interface exposes exactly one method, &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;void execute(JobExecutionContext ctx)&lt;/span&gt;, which is called when the job is triggered.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;c)&lt;/b&gt; Provide the &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;quartz-jobs.xml&lt;/span&gt; file that is indicated in the extra configuration in step a) (the file name and path can be adjusted to your liking) with the appropriate timing to start your jobs. For our tasks we use Cron-like jobs, with the&amp;nbsp;Quartz CronTrigger (see &lt;a href="http://www.quartz-scheduler.org/api/2.0.0/org/quartz/CronTrigger.html"&gt;http://www.quartz-scheduler.org/api/2.0.0/org/quartz/CronTrigger.html&lt;/a&gt;). An example configuration is:&lt;br /&gt;&lt;pre class="brush:xml"&gt;&lt;job-scheduling-data version="1.8" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.quartz-scheduler.org/xml/JobSchedulingData" xsi:schemalocation="http://www.quartz-scheduler.org/xml/JobSchedulingData http://www.quartz-scheduler.org/xml/job_scheduling_data_1_8.xsd"&gt;&lt;br /&gt;  &lt;br /&gt;  &lt;pre-processing-commands&gt;&lt;delete-jobs-in-group&gt;*&lt;/delete-jobs-in-group&gt;  &lt;br /&gt;    &lt;delete-triggers-in-group&gt;*&lt;/delete-triggers-in-group&gt; &lt;br /&gt;  &lt;/pre-processing-commands&gt;&lt;processing-directives&gt;&lt;br /&gt;    &lt;overwrite-existing-data&gt;true&lt;/overwrite-existing-data&gt;&lt;br /&gt;    &lt;ignore-duplicates&gt;false&lt;/ignore-duplicates&gt; &lt;br /&gt;  &lt;/processing-directives&gt;&lt;br /&gt;  &lt;br /&gt;  &lt;schedule&gt;&lt;br /&gt;   &lt;job&gt;&lt;br /&gt;    &lt;name&gt;TestJob&lt;/name&gt;&lt;br /&gt;    &lt;job-class&gt;com.acme.quartz.TestJob&lt;/job-class&gt;&lt;br /&gt;   &lt;/job&gt;&lt;br /&gt;&lt;br /&gt;   &lt;trigger&gt;&lt;br /&gt;    &lt;cron&gt;&lt;br /&gt;     &lt;name&gt;TestCronTrigger&lt;/name&gt;&lt;br /&gt;     &lt;job-name&gt;TestJob&lt;/job-name&gt;&lt;br /&gt;     &lt;cron-expression&gt;0 0 3 ? * MON-FRI&lt;/cron-expression&gt;&lt;br /&gt;    &lt;/cron&gt;&lt;br /&gt;   &lt;/trigger&gt;&lt;br /&gt;  &lt;/schedule&gt;    &lt;br /&gt;&lt;br /&gt; &lt;/job-scheduling-data&gt;&lt;br /&gt;&lt;/pre&gt;In this example the task executed by the com.acme.quartz.TestJob class is triggered at 3:00 AM on weekdays.&lt;br /&gt;&lt;br /&gt;One last &lt;b&gt;CAVEAT&lt;/b&gt;: On Windows, the &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;${jboss.server.home.dir}&lt;/span&gt; expression resolves to a String that contains backward slashes ('\') instead of forward slashes as path delimiter. The way the Quartz extension for JBoss reads in the properties is not able to cope with that, so you may need to provide a full path explicitly for any file names.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3925928603549971013-6419229388574853802?l=mauricedechateau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mauricedechateau.blogspot.com/feeds/6419229388574853802/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://mauricedechateau.blogspot.com/2011/07/external-quartz-on-jboss-51.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3925928603549971013/posts/default/6419229388574853802'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3925928603549971013/posts/default/6419229388574853802'/><link rel='alternate' type='text/html' href='http://mauricedechateau.blogspot.com/2011/07/external-quartz-on-jboss-51.html' title='&apos;External&apos; Quartz on JBoss 5.1'/><author><name>Maurice de Chateau</name><uri>https://profiles.google.com/111735333878743353142</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-srAZJqeqcc4/AAAAAAAAAAI/AAAAAAAAAE8/GRJGUoLka70/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3925928603549971013.post-4229206341248638833</id><published>2011-01-14T14:48:00.000+01:00</published><updated>2011-12-10T09:55:10.146+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JBoss'/><title type='text'>Use Apache as a secure (reverse) proxy for JBoss 5 AS/EAP</title><content type='html'>This task can be divided into two independent components (configure Apache to use SSL, set up Apache as a reverse proxy for JBoss) and a single step to make those two work together. The guidelines below have been successfully tested on an Apache 2.2.17/JBoss EAP 5.1.0.GA combination, the latter using Tomcat native libs, on a single server.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Part 1: Use SSL for access to Apache&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;1)&lt;/b&gt; &lt;a href="http://httpd.apache.org/download.cgi"&gt;Download&lt;/a&gt; and install the Apache Httpd server (version 2.2.6 or higher, 2.2.17 is the current). The folder in which the server is installed is referred to as APACHE_HOME further on.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;2)&lt;/b&gt; In APACHE_HOME/conf/httpd.conf, un-comment the following lines:&lt;br /&gt;&lt;pre class="brush:xml"&gt;    LoadModule ssl_module modules/mod_ssl.so&lt;br /&gt;&lt;br /&gt;    Include conf/extra/httpd-ssl.conf&lt;br /&gt;&lt;/pre&gt;Then comment the following one (to restrict access without SSL):&lt;br /&gt;&lt;pre class="brush:xml"&gt;    #Listen 80&lt;br /&gt;&lt;/pre&gt;&lt;b&gt;3)&lt;/b&gt; Put your certificate and key in the APACHE_HOME/conf folder, and (if necessary) change the names in APACHE_HOME/conf/extra/httpd-ssl.conf entries to match:&lt;br /&gt;&lt;pre class="brush:xml"&gt;    SSLCertificateFile "[APACHE_HOME]/conf/server.crt"&lt;br /&gt;    SSLCertificateKeyFile "[APACHE_HOME]/conf/server.key"&lt;br /&gt;&lt;/pre&gt;If you don’t have a CA certificate, you can create a self-signed certificate for testing purposes, see e.g. the &lt;a href="http://www.openssl.org/support/faq.html"&gt;OpenSSL FAQ&lt;/a&gt; how to do so. An OpenSSL executable is provided in the APACHE_HOME/bin folder.&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Remark&lt;/u&gt;: On Windows platforms it is not possible to use the SSLPassPhraseDialog-parameter (in httpd-ssl.conf) with the default value ‘builtin’. The simplest (albeit not the safest) solution is to remove the passphrase from the key, removing the need for Apache to ask for it at startup.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;4)&lt;/b&gt; (Re-)start the Apache server and test whether it works as expected… and don’t forget the ‘http&lt;b&gt;s&lt;/b&gt;://’!&lt;br /&gt;&lt;br /&gt;For an extensive explanation of the SSL configuration possibilities see &lt;a href="http://httpd.apache.org/docs/2.2/mod/mod_ssl.html"&gt;Apache Module ssl_mod&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Part 2: Set Apache up as a reverse proxy for JBoss&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;1)&lt;/b&gt; &lt;a href="http://tomcat.apache.org/download-connectors.cgi"&gt;Download&lt;/a&gt; the mod_jk connector (version 1.2.15 or higher, 1.2.31 is the current), rename the ‘mod_jk-1.2.[*]-httpd-2.2.x.so’ file to ‘mod_jk.so’ and move it to the APACHE_HOME/modules folder.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;2)&lt;/b&gt; Add the following line to APACHE_HOME/conf/httpd.conf:&lt;br /&gt;&lt;pre class="brush:xml"&gt;    Include conf/mod-jk.conf&lt;br /&gt;&lt;/pre&gt;&lt;b&gt;3)&lt;/b&gt; Create a new file in APACHE_HOME/conf with the name ‘mod-jk.conf’, and fill it with:&lt;br /&gt;&lt;pre class="brush:xml"&gt;    LoadModule jk_module modules/mod_jk.so&lt;br /&gt;&lt;br /&gt;    JkWorkersFile conf/workers.properties&lt;br /&gt;&lt;br /&gt;    JkLogFile logs/mod_jk.log&lt;br /&gt;    JkLogLevel info&lt;br /&gt;    JkLogStampFormat "[%a %b %d %H:%M:%S %Y]"&lt;br /&gt;    JkRequestLogFormat "%w %V %T"&lt;br /&gt;&lt;br /&gt;    JkOptions +ForwardKeySize +ForwardURICompatUnparsed -ForwardDirectories&lt;br /&gt;&lt;br /&gt;    # Mount your applications&lt;br /&gt;    ###JkMount /application/* loadbalancer&lt;br /&gt;    # Mount all URLs:&lt;br /&gt;    JkMount /* node1&lt;br /&gt;&lt;br /&gt;    # You can addionally use external file for mount points.&lt;br /&gt;    ###JkMountFile conf/uriworkermap.properties&lt;br /&gt;    # Mount file reload check interval in secs (0 = turned off).&lt;br /&gt;    ###JkMountFileReload 60&lt;br /&gt;&lt;br /&gt;    # Add shared memory. Used only on unix platforms. The shm file is used by balancer and status workers.&lt;br /&gt;    ###JkShmFile run/jk.shm&lt;br /&gt;&lt;br /&gt;    # Add jkstatus for managing runtime data:&lt;br /&gt;    &amp;lt;Location /jkstatus/&amp;gt;&lt;br /&gt;        JkMount status&lt;br /&gt;        Order deny,allow&lt;br /&gt;        Deny from all&lt;br /&gt;        Allow from 127.0.0.1&lt;br /&gt;    &amp;lt;/Location&amp;gt;&lt;br /&gt;&lt;/pre&gt;When not all requests are to be redirected to node1 the line starting with ‘JkMount’ must be adjusted. Furthermore it is possible to use a separate properties file (using ‘JkMountFile’, with entries following the pattern ‘URL=worker’, e.g. ‘/jmx-console=node1’) if you need a more extensive redirection scheme.&lt;br /&gt;&lt;br /&gt;In the configuration above the access to the status manager (worker with ID ‘status’) is restricted to clients running on the same host, just for illustrative purposes.&lt;br /&gt;&lt;br /&gt;See the &lt;a href="http://tomcat.apache.org/connectors-doc/reference/apache.html"&gt;Tomcat connector reference&lt;/a&gt; for further details and possibilities.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;4)&lt;/b&gt; Create a new file in APACHE_HOME/conf named&amp;nbsp; ‘workers.properties’, &amp;nbsp;and put the following in it:&lt;br /&gt;&lt;pre class="brush:xml"&gt;    # Define list of workers that will be used for mapping requests&lt;br /&gt;&lt;br /&gt;    # Define Node1&lt;br /&gt;    # modify the host as your host IP or DNS name.&lt;br /&gt;    worker.node1.type=ajp13&lt;br /&gt;    worker.node1.host=localhost&lt;br /&gt;    worker.node1.port=8009&lt;br /&gt;    worker.node1.ping_mode=A&lt;br /&gt;    #worker.node1.connection_pool_size=10 # Only if the number of allowed connections to the Httpd is higher than maxThreads in JBoss server.xml.&lt;br /&gt;    #worker.node1.lbfactor=1 # Only used for a member worker of a load balancer.&lt;br /&gt;    # For non-loadbalanced setup with a single node:&lt;br /&gt;    worker.list=node1&lt;br /&gt;&lt;br /&gt;    # Define Node2&lt;br /&gt;    # modify the host as your host IP or DNS name.&lt;br /&gt;    #worker.node2.type=ajp13&lt;br /&gt;    #worker.node2.host= node2.mydomain.com&lt;br /&gt;    #worker.node2.port=8009&lt;br /&gt;    #worker.node2.ping_mode=A&lt;br /&gt;    #worker.node2.connection_pool_size=10&lt;br /&gt;    #worker.node2.lbfactor=1&lt;br /&gt;&lt;br /&gt;    # Load-balancing behaviour&lt;br /&gt;    #worker.loadbalancer.type=lb&lt;br /&gt;    #worker.loadbalancer.balance_workers=node1,node2&lt;br /&gt;    #worker.loadbalancer.sticky_session=Off # Enabled by default.&lt;br /&gt;    #worker.list=loadbalancer&lt;br /&gt;&lt;br /&gt;    # Status worker for managing load balancer&lt;br /&gt;    worker.status.type=status&lt;br /&gt;    worker.list=status&lt;br /&gt;&lt;/pre&gt;Most lines above are commented out, since we’re aiming for a configuration for a single node without loadbalancing. It is straightforward to add more nodes, with or without loadbalancing; just pay attention to the fact that with loadbalancing the worker.list should not refer to the separate nodes but only to the loadbalancer worker.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;5)&lt;/b&gt; For each (JBoss-)node a ‘jvmRoute’ attribute&amp;nbsp; must be added to the &amp;lt;Engine&amp;gt;-element in JBOSS_HOME/server/[configuration]/deploy/jbossweb.sar/server.xml, using the corresponding name from the mod_jk-configuration as a parameter:&lt;br /&gt;&lt;pre class="brush:xml"&gt;    &amp;lt;Engine name="jboss.web" defaulthost="localhost" jvmroute="node1"&amp;gt;&lt;br /&gt;&lt;/pre&gt;And for JBoss AS/EAP version 5 and above that is all that is required!&lt;br /&gt;&lt;br /&gt;&lt;b&gt;6)&lt;/b&gt; If you didn't configure Apache to use SSL, you can now (re-)start the JBoss en Apache servers and test whether the redirecting functions as expected…&lt;br /&gt;If you did configure SSL for Apache, hang on just a bit more...&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Part 3: Combining the twee solutions above&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;To be able to access Apache using SSL after which the request is passed to the JBoss instance over AJP, one last adjustment is required:&lt;br /&gt;&lt;br /&gt;&lt;b&gt;1)&lt;/b&gt; Move the JkMount directives from the APACHE_HOME/conf/mod-jk.conf file to the APACHE_HOME/conf/extra/httpd-ssl.conf file, and make sure they’re within the &amp;lt;VirtualHost&amp;gt; tags:&lt;br /&gt;&lt;pre class="brush:xml"&gt;    &amp;lt;VirtualHost _default_:443&amp;gt;&lt;br /&gt;&lt;br /&gt;    […]&lt;br /&gt;&lt;br /&gt;    JkMount /* node1&lt;br /&gt;    &amp;lt;Location /jkstatus/&amp;gt;&lt;br /&gt;        JkMount status&lt;br /&gt;        Order deny,allow&lt;br /&gt;        Deny from all&lt;br /&gt;        Allow from 127.0.0.1&lt;br /&gt;    &amp;lt;/Location&amp;gt;&lt;br /&gt;&lt;br /&gt;    &amp;lt;/VirtualHost&amp;gt;&lt;br /&gt;&lt;/pre&gt;After a restart of the Apache server the pages served by JBoss will be available over HTTPS from Apache (port 443).&lt;br /&gt;&lt;br /&gt;Be aware that they are also still available over HTTP from JBoss directly (on port 8080), since the configuration above didn’t remove that (default) situation. To accomplish that, you should comment the HTTP connector entry in the server.xml file of jbossweb.sar.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3925928603549971013-4229206341248638833?l=mauricedechateau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mauricedechateau.blogspot.com/feeds/4229206341248638833/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://mauricedechateau.blogspot.com/2011/01/use-apache-as-secure-reverse-proxy-for.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3925928603549971013/posts/default/4229206341248638833'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3925928603549971013/posts/default/4229206341248638833'/><link rel='alternate' type='text/html' href='http://mauricedechateau.blogspot.com/2011/01/use-apache-as-secure-reverse-proxy-for.html' title='Use Apache as a secure (reverse) proxy for JBoss 5 AS/EAP'/><author><name>Maurice de Chateau</name><uri>https://profiles.google.com/111735333878743353142</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-srAZJqeqcc4/AAAAAAAAAAI/AAAAAAAAAE8/GRJGUoLka70/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3925928603549971013.post-2024498406130548978</id><published>2010-12-29T12:26:00.002+01:00</published><updated>2011-01-07T10:15:21.105+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><title type='text'>No, labels in Java are not 'evil'... at least not per se!</title><content type='html'>&lt;span class="Apple-style-span" style="font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 14px;"&gt;Last week I got into an argument with some colleagues about the use of labels in Java for escaping nested loops. The&amp;nbsp;general&amp;nbsp;consensus&amp;nbsp;was some along the line of "using break or continue with a label is evil, because it is a goto". While I feel the construct should be applied with care and many instances in which it could be applied a refactoring into e.g. a call to a separate method makes sense, it certainly has its use and cannot simply be deemed evil.&lt;/span&gt;&lt;br /&gt;&lt;div style="font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 14px;"&gt;&lt;span style="font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 14px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: Verdana, Arial, Helvetica, sans-serif; font-size: small;"&gt;&lt;span style="font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 14px;"&gt;I can think of a couple of sources for the misconception:&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: Verdana, Arial, Helvetica, sans-serif;"&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 14px;"&gt;When Dijkstra published his letter in Communications of the ACM "&lt;/span&gt;&lt;span style="font-family: sans-serif; line-height: 19px;"&gt;Go To Statement Considered Harmful&lt;/span&gt;&lt;span style="font-size: 14px;"&gt;" way back in 1968 this led to a lot of controversy too, and somehow only the title of the letter has stuck with a lot of people - but not its original contents nor its true intent.&lt;/span&gt;&lt;/li&gt;&lt;li style="font-size: small;"&gt;&lt;span style="font-size: 14px;"&gt;Java has the reserved keyword goto, but doesn't allow its use. James Gosling outlawed it, so it must be bad - nevertheless he did put in the labels.&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div style="font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 14px;"&gt;So I feel that not getting the whole picture is responsible for such misinformedness in some (or maybe even: many) programmers. But hey, don't just take my word for it!&lt;/div&gt;&lt;div style="font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 14px;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: Verdana, Arial, Helvetica, sans-serif;"&gt;&lt;span style="font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 14px;"&gt;In his book 'Thinking in Java'&amp;nbsp;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-size: 14px;"&gt;Bruce Eckel explains that&amp;nbsp;"&lt;/span&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="color: #38761d;"&gt;In Dijkstra’s “goto considered harmful” paper, what he specifically objected to was the labels, not the goto. He observed that the number of bugs seems to increase with the number of labels in a program. Labels and gotos make programs difficult to analyze statically, since it introduces cycles in the program execution graph. Note that Java labels don’t suffer from this problem, since they are constrained in their placement and can’t be used to transfer control in an ad hoc manner. It’s also interesting to note that this is a case where a language feature is made more useful by restricting the power of the statement.&lt;/span&gt;&lt;/i&gt;&lt;span class="Apple-style-span" style="font-size: 14px;"&gt;"&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 14px;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: arial; font-size: small;"&gt;&lt;span style="font-family: Verdana, Arial, Helvetica, sans-serif;"&gt;&lt;span style="font-size: 14px;"&gt;&lt;a href="http://david.tribble.com/text/goto.html"&gt;In a (lengthy and by now five-year-old) retrospective of Dijkstra's paper&lt;/a&gt;, David Tribble illustrates that goto-like constructs are business-as-usual in modern programming languages without it being apparent al the time, and that constructs mentioned by Dijkstra include not only labels for exiting loops, but also e.g. exception handling (try-catch-finally blocks).&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: Verdana, Arial, Helvetica, sans-serif; font-size: x-small;"&gt;&lt;span style="font-size: 14px;"&gt;Furthermore he also reaches the conclusion that&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 14px;"&gt;"&lt;/span&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="color: #38761d; font-family: Verdana, sans-serif;"&gt;Dijkstra's belief that unstructured goto statements are detrimental to good programming is still true. A&amp;nbsp;properly designed language should provide flow control constructs that are powerful enough to deal with almost any programming problem. By&amp;nbsp;the same token, programmers who must use languages that do not provide sufficiently flexible flow control statements should exercise restraint when using unstructured alternatives. This is the Tao of goto: knowing when to use it for good and when not to use it for evil.&lt;/span&gt;&lt;/i&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 14px;"&gt;"&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: arial; font-size: small;"&gt;&lt;span style="font-family: Verdana, Arial, Helvetica, sans-serif;"&gt;&lt;span style="font-size: 14px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: Verdana, Arial, Helvetica, sans-serif; font-size: x-small;"&gt;&lt;span style="font-size: 14px;"&gt;Dustin Marx &lt;a href="http://www.javaworld.com/community/node/3375"&gt;puts it nicely&lt;/a&gt; when he says&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: Verdana, Arial, Helvetica, sans-serif; font-size: x-small;"&gt;&lt;span style="font-size: 14px;"&gt;"&lt;/span&gt;&lt;/span&gt;&lt;span style="line-height: 20px;"&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="color: #38761d; font-family: Verdana, sans-serif;"&gt;The more I work in the software development industry, the more convinced I become that there are&amp;nbsp;few absolutes in software development&amp;nbsp;and that extremist positions will almost always be wrong at one point or another. I generally shy away from use of goto or goto-like code, but there are times when it is the best code for the job. Although Java does not have direct goto support, it provides goto-like support that meets most of my relatively infrequent needs for such support.&lt;/span&gt;&lt;/i&gt;&lt;/span&gt;&lt;span style="font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 14px;"&gt;"&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 14px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 14px;"&gt;Now I'm not saying that the above is the conclusive evidence that proves my point. But you may interpret it as an incentive to be a little more openminded when it comes to certain 'conventional wisdoms' surrounding programming...&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 14px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 14px;"&gt;&lt;i&gt;&lt;u&gt;Update&lt;/u&gt;&lt;/i&gt;: If you take a look e.g. at &lt;a href="http://arhipov.blogspot.com/2011/01/java-bytecode-fundamentals.html"&gt;this nice article on Java bytecode&lt;/a&gt;, specifically the bit about exception handling, you can see what's happening under the hood. That's right, those are just plain vanilla gotos at work when you use a try-catch block!&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3925928603549971013-2024498406130548978?l=mauricedechateau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mauricedechateau.blogspot.com/feeds/2024498406130548978/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://mauricedechateau.blogspot.com/2010/12/no-labels-in-java-are-not-evil-at-least.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3925928603549971013/posts/default/2024498406130548978'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3925928603549971013/posts/default/2024498406130548978'/><link rel='alternate' type='text/html' href='http://mauricedechateau.blogspot.com/2010/12/no-labels-in-java-are-not-evil-at-least.html' title='No, labels in Java are not &apos;evil&apos;... at least not per se!'/><author><name>Maurice de Chateau</name><uri>https://profiles.google.com/111735333878743353142</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-srAZJqeqcc4/AAAAAAAAAAI/AAAAAAAAAE8/GRJGUoLka70/s512-c/photo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3925928603549971013.post-44466238343393726</id><published>2010-11-17T10:31:00.000+01:00</published><updated>2010-11-17T10:31:13.686+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='jBPM'/><title type='text'>Uploading jBPM .par files (from a repository)</title><content type='html'>Once you've passed the testing cycles during development, you want to make sure that the processes that get deployed onto the production environment are indeed versions that were released according to your formal build procedure - if you have such in place of course.&lt;br /&gt;&lt;br /&gt;In our case, that means that the officially released processes are available from a Maven repository. Now there's nothing wrong with retrieving a newly released process archive and using e.g. the jBPM console to upload it. That is, if there's just one such .par file to upload.&lt;br /&gt;&lt;br /&gt;My current project produces no less than 16 process archives, one of which is referenced in multiple locations - so it is not uncommon to have more than 20 process instances started during the course of a single request we're processing.&lt;br /&gt;&lt;br /&gt;Now regardless of the question whether we chose the right granularity for our processes (which I think we did, of course), this turned into quite some work for each deployment cycle, keeping track of which .par file was deployed and whether it was in the correct sequence (we're not using late binding for sub-processes). Performing this task had become too error-prone to allow it for the production environment.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Ant to the rescue?&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;The &lt;a href="http://docs.jboss.com/jbpm/v3.2/userguide/html_single/#deployingaprocessarchive"&gt;user guide&lt;/a&gt; states that there are three ways to deploy the process archives (they forget about the jBPM console altogether there):&lt;br /&gt;&lt;ul&gt;&lt;li&gt;The process designer tool; an Eclipse plug-in that is part of JBoss Tools. This is of course not a real option, since we want to be able to deploy process archives without having to start up an IDE.&lt;/li&gt;&lt;li&gt;The &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;org.jbpm.ant.DeployProcessTask&lt;/span&gt;; an Ant task available from the regular jBPM jar file. While an Ant build actually is a good option for a command-line alternative, this particular task is simply too much: it starts up a complete jBPM context for uploading the process directly to the database, and as such requires all of the applicable configuration. I prefer to have as little direct database access from external hosts as possible (e.g. for security considerations), and this approach doesn't accomplish that.&lt;/li&gt;&lt;li&gt;Programmatically; using the jBPM API directly. That is basically just more complex than using the Ant task, so that's not the way to go either (in this case).&lt;/li&gt;&lt;/ul&gt;So unfortunately these suggestions don't give us the ease-of-use that the jBPM console did, just selecting the .par file and clicking the 'Deploy' button, and we had to search a little further.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Reuse the input method of the designer&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;A closer look at the &lt;a href="http://docs.jboss.com/jbpm/v3.2/userguide/html_single/#jpdlgraphicalprocessdesigner"&gt;GPD designer plug-in&lt;/a&gt; shows that its upload functionality is little more than an HTTP client, calling the POST method of the &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;ProcessUploadServlet&lt;/span&gt; of the jBPM console. This servlet then uses the functionality of the jBPM API (as mentioned above for the Ant task and the programmatic approach). This entrance into the jBPM deployment is exactly what we need: it's simple in just requiring the .par file to be entered, any database interaction is taken care of by the servlet, any security issues can be addressed by the deployment of the console (see e.g. how that's done in the SOA platform).&lt;br /&gt;&lt;br /&gt;So, using Apache's HttpClient library I finally came up with something like the following:&lt;br /&gt;&lt;pre class="brush:java"&gt;package org.jbpm.par;&lt;br /&gt;&lt;br /&gt;import java.io.InputStream;&lt;br /&gt;import java.net.URL;&lt;br /&gt;&lt;br /&gt;import org.apache.http.HttpResponse;&lt;br /&gt;import org.apache.http.client.HttpClient;&lt;br /&gt;import org.apache.http.client.methods.HttpPost;&lt;br /&gt;import org.apache.http.entity.mime.MultipartEntity;&lt;br /&gt;import org.apache.http.entity.mime.content.ContentBody;&lt;br /&gt;import org.apache.http.entity.mime.content.InputStreamBody;&lt;br /&gt;import org.apache.http.impl.client.DefaultHttpClient;&lt;br /&gt;&lt;br /&gt;public class ProcessUploader {&lt;br /&gt;    public static void main(String[] args) {&lt;br /&gt;        HttpClient client = null;&lt;br /&gt;        try {&lt;br /&gt;            // Get the input parms: first the file name, then the URL String for its location (in the repo).&lt;br /&gt;            String fileName = args[0];&lt;br /&gt;            URL url = new URL(args[1]);&lt;br /&gt;&lt;br /&gt;            // Prepare the request.&lt;br /&gt;            HttpPost request = new HttpPost("http://localhost:8080/jbpm-console/upload");&lt;br /&gt;            ContentBody body = new InputStreamBody(url.openStream(), "application/x-zip-compressed", fileName);&lt;br /&gt;            MultipartEntity entity = new MultipartEntity();&lt;br /&gt;            entity.addPart("bin", body);&lt;br /&gt;            request.setEntity(entity);&lt;br /&gt;&lt;br /&gt;            // Execute the request.&lt;br /&gt;            client = new DefaultHttpClient();&lt;br /&gt;            HttpResponse response = client.execute(request);&lt;br /&gt;&lt;br /&gt;            // You can examine the the response further by looking at its contents:&lt;br /&gt;            InputStream is = response.getEntity().getContent(); // And e.g. print it to screen...&lt;br /&gt;        } catch (Exception ex) {&lt;br /&gt;            ex.printStackTrace();&lt;br /&gt;        } finally {&lt;br /&gt;            if (client != null) {&lt;br /&gt;                // Clean up after yourself.&lt;br /&gt;                client.getConnectionManager().shutdown();&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;While this simple example takes a single URL for a .par file (along with the corresponding file name) on the command line, we'll be using  the same principle with a standard properties file listing all of the URLs for our process archives and looping through that list executing a request for each file. And these URLs will be pointing to our Maven repository, of course, allowing us to configure the correct versions for each release.&lt;br /&gt;&lt;br /&gt;Note that the URL for the upload servlet is hard-coded in the example; if you're uploading your .par files from a different host, you'd want to configure the host on which jBPM runs differently than 'localhost', of course.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3925928603549971013-44466238343393726?l=mauricedechateau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mauricedechateau.blogspot.com/feeds/44466238343393726/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://mauricedechateau.blogspot.com/2010/11/uploading-jbpm-par-files-from.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3925928603549971013/posts/default/44466238343393726'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3925928603549971013/posts/default/44466238343393726'/><link rel='alternate' type='text/html' href='http://mauricedechateau.blogspot.com/2010/11/uploading-jbpm-par-files-from.html' title='Uploading jBPM .par files (from a repository)'/><author><name>Maurice de Chateau</name><uri>https://profiles.google.com/111735333878743353142</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-srAZJqeqcc4/AAAAAAAAAAI/AAAAAAAAAE8/GRJGUoLka70/s512-c/photo.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3925928603549971013.post-2656137142138923685</id><published>2010-07-30T11:00:00.001+02:00</published><updated>2010-07-30T11:03:21.217+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='jBPM'/><title type='text'>Adding task nodes dynamically at runtime</title><content type='html'>I find that sometimes there's a good reason not to include all possible paths in a process definition at design time. Some of the more generic, non-functional paths can be included dynamically at runtime, in order not to clutter the process definition and be able to focus on the 'real' functionality your process needs to automate.&lt;br /&gt;&lt;br /&gt;This goes e.g. for the handling of exceptions, &lt;a href="http://www.schabell.org/2010/04/jbpm-v32-custom-exception-framework.html"&gt;as described here&lt;/a&gt;, where an automatic retry is accomplished by adding a transition dynamically from a node in which an exception occurs to itself. You probably don't want to add such 'self-transitions' at design time (that's just butt-ugly).&lt;br /&gt;&lt;br /&gt;When you add such a path, it may include a TaskNode at some point. It did for me, and this is how I solved that.&lt;br /&gt;&lt;br /&gt;The following code needs to run inside a jBPM context (obviously):&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:java"&gt;private void createDynamicTaskNode(ProcessInstance procInst, Node originatingNode, Node targetNode) {&lt;br /&gt;        // Add the dynamic task node.&lt;br /&gt;        // - Create the task.&lt;br /&gt;        Task task = new Task("Dynamic task name");&lt;br /&gt;        task.setProcessDefinition(procInst.getProcessDefinition());&lt;br /&gt;        procInst.getTaskMgmtInstance().getTaskMgmtDefinition().addTask(task);&lt;br /&gt;        task.setPooledActorsExpression("Dynamic task executors"); // Or use an actor ID.&lt;br /&gt;        // - Create the node.&lt;br /&gt;        TaskNode taskNode = new TaskNode("Dynamic task node name");&lt;br /&gt;        taskNode.addTask(task); // Adds both ends of the association TaskNode &lt;-&gt; Task.&lt;br /&gt;        procInst.getProcessDefinition().addNode(taskNode); // Adds both ends of the association ProcessDefinition &lt;-&gt; Node.&lt;br /&gt;&lt;br /&gt;        // Create transition between originating node and dynamic task node.&lt;br /&gt;        Transition transition = new Transition("Transition to dynamic task node");&lt;br /&gt;        originatingNode.addLeavingTransition(transition);&lt;br /&gt;        taskNode.addArrivingTransition(transition);&lt;br /&gt;        // Create transition between dynamic task node and target node.&lt;br /&gt;        transition = new Transition();&lt;br /&gt;        taskNode.addLeavingTransition(transition);&lt;br /&gt;        targetNode.addArrivingTransition(transition);&lt;br /&gt;    }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Basically it follows the same scenario for creating the node and transitions as jBPM does when it parses the JPDL process definition, using a lot of the defaults involved (such as that the task is blocking and ending it will signal the process instance to continue).&lt;br /&gt;If you needs any of the non-standard options, you may want to read &lt;a href="http://docs.jboss.com/jbpm/v3.2/userguide/html_single/#taskmanagement"&gt;the manual&lt;/a&gt; to see what these options can bring you.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3925928603549971013-2656137142138923685?l=mauricedechateau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mauricedechateau.blogspot.com/feeds/2656137142138923685/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://mauricedechateau.blogspot.com/2010/07/adding-task-nodes-dynamically-at.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3925928603549971013/posts/default/2656137142138923685'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3925928603549971013/posts/default/2656137142138923685'/><link rel='alternate' type='text/html' href='http://mauricedechateau.blogspot.com/2010/07/adding-task-nodes-dynamically-at.html' title='Adding task nodes dynamically at runtime'/><author><name>Maurice de Chateau</name><uri>https://profiles.google.com/111735333878743353142</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-srAZJqeqcc4/AAAAAAAAAAI/AAAAAAAAAE8/GRJGUoLka70/s512-c/photo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3925928603549971013.post-7785096576412508879</id><published>2010-04-09T14:21:00.005+02:00</published><updated>2010-04-12T11:46:29.980+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='jBPM'/><title type='text'>Automatic continuations in a jBPM Node</title><content type='html'>The normal pattern of using a Node would be to execute some Java  code from within an Action directly attached to the Node, but as the  documentation states, that means this code will also be responsible for  continuing the process execution:&lt;br /&gt;&lt;br /&gt;"&lt;i&gt;The nodetype node expects one subelement action. The action is executed when the execution arrives in the node. The code you write in the actionhandler can do anything you want but it &lt;b&gt;is also responsible for propagating the execution&lt;/b&gt;&lt;/i&gt;."&lt;br /&gt;&lt;br /&gt;And you may have a different opinion, but I think it's quite tedious to  have to repeat the same kind of boiler plate code in each and every  ActionHandler implementation used in Nodes, so I wanted to come up with a  way to do it more generically.&lt;br /&gt;&lt;br /&gt;This standard node type actually gives you a choice as it comes to its execution:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;as stated above you add an Action (directly to the Node) and have it execute that, or&lt;/li&gt;&lt;li&gt;you don't add an Action and have it leave through the default Transition.&lt;/li&gt;&lt;/ul&gt;How the latter would be useful is beyond me (but that's another discussion), you should be aware of this behavior when you're e.g. attaching Actions to the 'node-enter' event only and not directly to the Node. You'd have a hard time figuring out what happens if you would expect it would be possible to leave the Node through another than the default Transition (it's possible, but you'd have to change the order of the Transitions on runtime, which you probably want to stay away from as far as possible).&lt;br /&gt;&lt;br /&gt;The simple approach I chose to illustrate this was to provide an abstract base class, which implements the ActionHandler interface, which has to be extended by all action handlers in your code base. Well, nearly all, but I'll get back to that later. Surely there would be other approaches that will come up with the same result (like annotations or aspects); just knock yourself out.&lt;br /&gt;Such a base class would look something like this:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:java"&gt;public abstract class AbstractActionHandler implements ActionHandler {&lt;br /&gt;    protected String transitionName;&lt;br /&gt;&lt;br /&gt;    public final void execute(ExecutionContext ctx) throws Exception {&lt;br /&gt;        performAction(ctx);&lt;br /&gt;&lt;br /&gt;        if (ctx.getEvent() == null) {&lt;br /&gt;            // When leaving the node we can either have a transition set to be taken or else take the default transition.&lt;br /&gt;            if (StringUtils.isBlank(transitionName)) {&lt;br /&gt;                ctx.getNode().leave(ctx);&lt;br /&gt;            } else {&lt;br /&gt;                ctx.getNode().leave(ctx, transitionName);&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    // To be implemented by concrete subclasses; execute the intended Java code and optionally set the transition to be taken.&lt;br /&gt;    public abstract void performAction(ExecutionContext ctx) throws Exception;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Now the main 'trick' here is to know when to continue the execution and when not to; as you can tell from the code above this can be derived from the fact whether an event is available in the execution context. At the basis of this fact is the knowledge at which places in a process definition Actions can be added (and when/how they're executed in those instances), and cross-reference that with the required point of continuation (an Action directly in a Node).&lt;br /&gt;&lt;br /&gt;You can add an Action at six different places:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Directly to a Node: which is what we're talking about here for having automatic continuation.&lt;/li&gt;&lt;li&gt;In an event (e.g. 'node-enter'): most of the time that's an explicit event in the process definition.&lt;/li&gt;&lt;li&gt;In a Transition: actually then it's executed from within a 'transition' event.&lt;/li&gt;&lt;li&gt;In a timer: here it's executed after the 'timer' event is fired, so not within it.&lt;/li&gt;&lt;li&gt;In an exception handler: executed from within &lt;span style="font-size: small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;GraphElement's raiseException(...)&lt;/span&gt;&lt;/span&gt; method, which also has no event associated with it, but does put the current Exception in the execution context.&lt;/li&gt;&lt;li&gt;Directly to the process definition (highest level): these are just for reference from within other elements, so not an 'extra' type in any sense - so we'll just forget about this one for now.&lt;/li&gt;&lt;/ul&gt;So for the second and third entries of this list the execution context has a current event; the first, fourth and the fifth don't. So the 'trick' as it is used in the above code fragment works for the first three, for the other two (timers and exception handlers) you shouldn't use that particular base class.&lt;br /&gt;It is however possible to extend the 'trick' for these other two instances, by checking the execution context for the availability of a timer (&lt;span style="font-size: small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;ctx.getTimer() == null&lt;/span&gt;&lt;/span&gt;) and/or the availability of an exception (&lt;span style="font-size: small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;ctx.getException() == null&lt;/span&gt;&lt;/span&gt;) respectively - it depends for which of the cases you want to provide a base class (or mechanism of your choice) in order to have these automatic continuations I was after.&lt;br /&gt;&lt;br /&gt;Credit where credit is due: thanks to Arnoud W. for the hint!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3925928603549971013-7785096576412508879?l=mauricedechateau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mauricedechateau.blogspot.com/feeds/7785096576412508879/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://mauricedechateau.blogspot.com/2010/04/automatic-continuations-in-jbpm-node.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3925928603549971013/posts/default/7785096576412508879'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3925928603549971013/posts/default/7785096576412508879'/><link rel='alternate' type='text/html' href='http://mauricedechateau.blogspot.com/2010/04/automatic-continuations-in-jbpm-node.html' title='Automatic continuations in a jBPM Node'/><author><name>Maurice de Chateau</name><uri>https://profiles.google.com/111735333878743353142</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-srAZJqeqcc4/AAAAAAAAAAI/AAAAAAAAAE8/GRJGUoLka70/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3925928603549971013.post-2285129588425697889</id><published>2009-11-24T15:48:00.006+01:00</published><updated>2011-12-10T09:56:10.548+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JBoss'/><category scheme='http://www.blogger.com/atom/ns#' term='jBPM'/><title type='text'>Running jBPM 3.2.8_SOA on JBoss EAP 4.3</title><content type='html'>For my current project, I've been putting together JBoss EAP 4.3 and jBPM 3.2.8_SOA. At my company, we don't have the full JBoss SOA stack, yet do have support contracts for the two separately. Needless to say, it was unlikely that they would behave nicely together out-of-the-box...&lt;br /&gt;&lt;br /&gt;The supported jBPM distribution comes as a zip file, lacking the installer that the community version does have. But once unzipped, there's a &lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;deploy/&lt;/span&gt; directory with everything that needs to be copied onto the app server. So at a first glance it seemed straightforward enough to copy the &lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;data/&lt;/span&gt; and &lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;deploy/&lt;/span&gt; directories from the &lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;deploy/server/default/&lt;/span&gt; folder of the unzipped distribution to the appropriate server base folder.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Wrong reference to JMS class&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;However, upon first starting up the server, it was indicated in the &lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;server.log&lt;/span&gt; file that an expected class for the MQ service MBeans (org.jboss.mq.server.jmx.Queue) could not be found. While I know this class was included in the libs distributed along with the 4.0.5 version of the app server, it is no longer found in the EAP 4.3 version and replaced since then. You'll need to replace these entries in the &lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;jbpm-mq-service.xml&lt;/span&gt; file (found in the &lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;deploy/jbpm&lt;/span&gt; directory):&lt;br /&gt;&lt;pre class="brush:xml"&gt;&lt;mbean code="org.jboss.mq.server.jmx.Queue" name="jboss.mq.destination:service=Queue,name=JbpmJobQueue"&gt;&lt;br /&gt;    &lt;depends optional-attribute-name="DestinationManager"&gt;jboss.mq:service=DestinationManager&lt;/depends&gt;&lt;br /&gt;&lt;/mbean&gt;&lt;br /&gt;&lt;br /&gt;&lt;mbean code="org.jboss.mq.server.jmx.Queue" name="jboss.mq.destination:service=Queue,name=JbpmCommandQueue"&gt;&lt;br /&gt;      &lt;depends optional-attribute-name="DestinationManager"&gt;jboss.mq:service=DestinationManager&lt;/depends&gt;&lt;br /&gt;&lt;/mbean&gt;&lt;br /&gt;&lt;/pre&gt;with these:&lt;br /&gt;&lt;pre class="brush:xml"&gt;&lt;mbean code="org.jboss.jms.server.destination.QueueService" name="jboss.messaging.destination:service=Queue,name=JbpmJobQueue" xmbean-dd="xmdesc/Queue-xmbean.xml"&gt;&lt;br /&gt;    &lt;depends optional-attribute-name="ServerPeer"&gt;jboss.messaging:service=ServerPeer&lt;/depends&gt;&lt;br /&gt;    &lt;depends&gt;jboss.messaging:service=PostOffice&lt;/depends&gt;&lt;br /&gt;&lt;/mbean&gt;&lt;br /&gt;&lt;br /&gt;&lt;mbean code="org.jboss.jms.server.destination.QueueService" name="jboss.messaging.destination:service=Queue,name=JbpmCommandQueue" xmbean-dd="xmdesc/Queue-xmbean.xml"&gt;&lt;br /&gt;    &lt;depends optional-attribute-name="ServerPeer"&gt;jboss.messaging:service=ServerPeer&lt;/depends&gt;&lt;br /&gt;    &lt;depends&gt;jboss.messaging:service=PostOffice&lt;/depends&gt;&lt;br /&gt;&lt;/mbean&gt;&lt;br /&gt;&lt;/pre&gt;and with those in place, the server starts up without any error messages in the log.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Unable to log onto the jBPM console&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;So the next step was trying to upload a process archive, but that plan was nipped in the bud by the login procedure of the jBPM console. Using a username-password combo that is in the default database entries (like the infamous admin/admin combo) I was denied access. The error logging threw me off at first in this case, as it complained about not being able to find the appropriate roles.properties and users.properties (e.g. like the ones provided for the JMX console). But adding these (in the &lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;deploy/jbpm/jsf-console.war/WEB-INF/classes/&lt;/span&gt; directory) simply left me with a 403 Access Denied page, and no logging whatsoever!&lt;br /&gt;&lt;br /&gt;The right answer was found in the &lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;jboss-web.xml&lt;/span&gt; (for the console). There the JAAS security domain is defined as "&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;java:/jaas/soa&lt;/span&gt;", while in the &lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;jboss-service.xml&lt;/span&gt; (in the &lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;deploy/jbpm/jbpm-service.sar/META-INF/&lt;/span&gt; directory) the name of the application is still "jbpm-console" - even though both are in the same distribution!&lt;br /&gt;&lt;br /&gt;Changing &lt;br /&gt;&lt;pre class="brush:xml"&gt;&lt;jaas:application-policy name="jbpm-console"&gt;&lt;br /&gt;   ...&lt;br /&gt;&lt;/jaas:application-policy&gt;&lt;br /&gt;&lt;/pre&gt;to&lt;br /&gt;&lt;pre class="brush:xml"&gt;&lt;jaas:application-policy name="soa"&gt;&lt;br /&gt;   ...&lt;br /&gt;&lt;/jaas:application-policy&gt;&lt;br /&gt;&lt;/pre&gt;in the latter file does the trick, although it is just as fine when you would change the security domain in the former to "&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;java:/jaas/jbpm-console&lt;/span&gt;", as long as the two are in sync.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Now with these two minor issues out of the way, I was able to deploy a simple process and run it. Not too bad for two distributions that weren't designed to work together. Possibly there are still some issues left to be solved, which I then undoubtedly will run into during the course of this project. If so, I'll simply dedicate another post about it...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3925928603549971013-2285129588425697889?l=mauricedechateau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mauricedechateau.blogspot.com/feeds/2285129588425697889/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://mauricedechateau.blogspot.com/2009/11/running-jbpm-328soa-on-jboss-eap-43.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3925928603549971013/posts/default/2285129588425697889'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3925928603549971013/posts/default/2285129588425697889'/><link rel='alternate' type='text/html' href='http://mauricedechateau.blogspot.com/2009/11/running-jbpm-328soa-on-jboss-eap-43.html' title='Running jBPM 3.2.8_SOA on JBoss EAP 4.3'/><author><name>Maurice de Chateau</name><uri>https://profiles.google.com/111735333878743353142</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-srAZJqeqcc4/AAAAAAAAAAI/AAAAAAAAAE8/GRJGUoLka70/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3925928603549971013.post-2542476091062935295</id><published>2008-12-15T19:50:00.004+01:00</published><updated>2009-11-25T15:09:25.872+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='jBPM'/><title type='text'>Writing a custom ClassLoader for jBPM</title><content type='html'>Within our &lt;a href="http://www.jbpm.org/"&gt;jBPM process engine&lt;/a&gt; we're dealing with dependencies on libraries that are, well..., not completely stable. The code in the node handlers is calling our SOA layer through generated API classes, which automagically take care of several boiler plate tasks (such as security) and are deployed as jars along with our process engine. The SOA layer evolves, so in time a number of versions has come to exist.&lt;br /&gt;&lt;br /&gt;We encountered a problem because we're running several process definitions within one engine deployment. This includes both entirely different processes as well as new versions of already running process definitions. Our base of automated business processes has grown over time, with older process implementations relying on the early SOA API and the newer process implementations taking advantage of the later API additions. There are dependencies to different versions of the API - and while strict backwards compatibility might have solved this issue for us, in practice this proved not quite feasible.&lt;br /&gt;&lt;br /&gt;So what were the issues we were trying to solve?&lt;br /&gt;&lt;ul&gt;&lt;li&gt;There are different versions of the generated API classes corresponding to different versions of the SOA services. One deployment of jBPM must be able to run processes that rely on different versions next to each other.&lt;/li&gt;&lt;li&gt;We wanted to be able to configure the dependency per process definition, but also for versions of a definition, so that a new incarnation of a process may take advantage of a new (and hopefully improved) version of a web service.&lt;/li&gt;&lt;li&gt;Not only the correct version of the API classes needs to be used, also the corresponding web service endpoints has to be available to the code running a process instance.&lt;/li&gt;&lt;/ul&gt;The configuration had to be external to the process archive, so it can be adjusted at deploy time. We've settled for a simple XML format, which allows for all required information to be present using minimum complexity:&lt;br /&gt;&lt;pre class="brush:xml"&gt;&lt;jbpm_custom_cfg&gt;&lt;br /&gt;   &lt;api_jar_dir value="${server.home}/lib/ext/api" /&gt;&lt;br /&gt;   &lt;process id="process1" max_version="3"&gt;&lt;br /&gt;      &lt;service name="service1" jar="service1-api-1_7.jar" endpoint="http://where.ever.com/service1-v1"&gt;&lt;br /&gt;      &lt;/service&gt;&lt;br /&gt;      &lt;service name="service2" jar="service2-api-1_0.jar" endpoint="http://where.ever.com/service2-v1"&gt;&lt;br /&gt;      &lt;/service&gt;&lt;br /&gt;   &lt;/process&gt;&lt;br /&gt;   &lt;process id="process1" min_version="4" max_version="6"&gt;&lt;br /&gt;      &lt;service name="service1" jar="service1-api-2_1.jar" endpoint="http://where.ever.com/service1-v2"&gt;&lt;br /&gt;      &lt;/service&gt;&lt;br /&gt;      &lt;service name="service2" jar="service2-api-1_3.jar" endpoint="http://where.ever.com/service2-v1"&gt;&lt;br /&gt;      &lt;/service&gt;&lt;br /&gt;   &lt;/process&gt;&lt;br /&gt;   &lt;process id="process1" min_version="7"&gt;&lt;br /&gt;      &lt;service name="service1" jar="service1-api-2_4.jar" endpoint="http://where.ever.com/service1-v2"&gt;&lt;br /&gt;      &lt;/service&gt;&lt;br /&gt;      &lt;service name="service2" jar="service2-api-2_0.jar" endpoint="http://where.ever.com/service2-v2"&gt;&lt;br /&gt;      &lt;/service&gt;&lt;br /&gt;   &lt;/process&gt;&lt;br /&gt;   &lt;process id="process2"&gt;&lt;br /&gt;      &lt;service name="service2" jar="service2-api-2_0.jar" endpoint="http://where.ever.com/service2-v2"&gt;&lt;br /&gt;      &lt;/service&gt;&lt;br /&gt;      &lt;service name="service3" jar="service3-api-1_1.jar" endpoint="http://where.ever.com/service3-v1"&gt;&lt;br /&gt;      &lt;/service&gt;&lt;br /&gt;   &lt;/process&gt;&lt;br /&gt;&lt;/jbpm_custom_cfg&gt;&lt;br /&gt;&lt;/pre&gt;This custom configuration consists of the following:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;One line indicating the directory in which all the API jars are deployed. Take care that this directory and the jars in it are not on the standard classpath, because then you're gonna be stuck with only one version, which is not compatible with all of the calling code.&lt;/li&gt;&lt;li&gt;At least one entry for each process definition. A single entry can be used for each separately deployed version of the definition (as for process2) or different entries for the different version ranges (indicated using the min_version and/or max_version attributes).&lt;/li&gt;&lt;li&gt;For each process definition (version range) the jar file and endpoint for each required web service is added. The name is used for querying by the client code.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;The way to include the correct jars to the classpath of a given process instance (running a certain process definition version) is through a custom class loader - a mechanism that is made available in &lt;a href="http://downloads.sourceforge.net/jbpm/jbpm-installer-3.3.0.GA.jar"&gt;jBPM version 3.3.0.GA&lt;/a&gt; - just set the 'jbpm.classloader' property in jbpm.cfg.xml to 'custom' and indicate the custom class loader by setting its name in the 'jbpm.classloader.classname' property. This custom class loader itself is almost too simple to mention: it extends from java.net.URLClassloader, and in the constructor it determines the name and version of the process definition before reading the applicable jar file names (as URLs) from the custom configuration file.&lt;br /&gt;&lt;br /&gt;We've put the actual reading from the XML file in a utility class; for reading from XML we could have gone completely overboard and set up a schema and compiled Java classes from it with JAXB. Instead we simply used &lt;a href="http://www.dom4j.org/"&gt;the dom4j library&lt;/a&gt; and a couple of simple XPath expressions to accomplish the same.&lt;br /&gt;&lt;br /&gt;Our utility class has the following interface:&lt;br /&gt;&lt;pre class="brush:java"&gt;public final class ConfigurationUtil {&lt;br /&gt;   public static URL[] getJarsForProcessDefinition(String processId, int version) throws IOException {...}&lt;br /&gt;   public static String getEndpointForProcessDefinition(&lt;br /&gt;      String processId, int version, String serviceName) throws IOException {...}&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;The first method delivers everything needed by the custom class loader's super class constructor. The second method reuses the XML parsing facility and allows the last requirement mentioned in the issues above to be satisfied efficiently.&lt;br /&gt;&lt;br /&gt;In all, writing a custom ClassLoader was not much of a task anymore once we figured out what kind of custom configuration was applicable to our situation...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3925928603549971013-2542476091062935295?l=mauricedechateau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mauricedechateau.blogspot.com/feeds/2542476091062935295/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://mauricedechateau.blogspot.com/2008/12/writing-custom-classloader-for-jbpm.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3925928603549971013/posts/default/2542476091062935295'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3925928603549971013/posts/default/2542476091062935295'/><link rel='alternate' type='text/html' href='http://mauricedechateau.blogspot.com/2008/12/writing-custom-classloader-for-jbpm.html' title='Writing a custom ClassLoader for jBPM'/><author><name>Maurice de Chateau</name><uri>https://profiles.google.com/111735333878743353142</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-srAZJqeqcc4/AAAAAAAAAAI/AAAAAAAAAE8/GRJGUoLka70/s512-c/photo.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3925928603549971013.post-5496147434887169221</id><published>2008-11-26T19:39:00.000+01:00</published><updated>2009-11-22T17:46:04.932+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Security'/><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><title type='text'>"Too many certificates in chain"? It just may be a corrupt keystore!</title><content type='html'>Recently we ran into some trouble with the keyword expansion functionality that CVS offers (way too much false positives in the comparisons), and we simply decided to turn it off for our sources. That meant changing the ASCII/Binary property of all files from "ASCII -kkv" to "ASCII -kk" (keyword compression). Problem solved, albeit in a rather crude way.&lt;br /&gt;&lt;br /&gt;Well, that sure bit us in the proverbial back end. The point is that when you change this property, you should be careful not to change it for files that were designated "binary". But we did.&lt;br /&gt;&lt;br /&gt;One side effect of this was that a keystore file, stored in CVS, now became ASCII as well; effectively corrupting the file for further use. When trying to read a key from it, I got the following stack trace:&lt;br /&gt;&lt;pre&gt;&lt;span style="font-size:100%;"&gt;Caused by: java.io.IOException: Too many certificates in chain&lt;br /&gt;   at sun.security.provider.JavaKeyStore.engineLoad(Unknown Source)&lt;br /&gt;   at java.security.KeyStore.load(Unknown Source)&lt;br /&gt;&lt;/span&gt;&lt;/pre&gt;In an attempt to locate the source for this, I stumbled upon this:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;a href="http://docjar.com/docs/api/sun/security/provider/JavaKeyStore.html#engineLoad%28InputStream,%20char%29"&gt;http://docjar.com/docs/api/sun/security/provider/JavaKeyStore.html#engineLoad(InputStream,%20char)&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;font-size:85%;" &gt;(just scroll down a bit, the top bar covers the important part!)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;So from that code I gather that the occurring problem is actually an OutOfMemoryError (which I feel is kind of creepy) that is caused by the keystore implementation trying to load a corrupted keystore file. I think it's unlikely that there will be so many chained certificates in any practical keystore that this will really lead to running out of memory, so next time I see this error message I surely will think 'keystore file corruption'!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3925928603549971013-5496147434887169221?l=mauricedechateau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mauricedechateau.blogspot.com/feeds/5496147434887169221/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://mauricedechateau.blogspot.com/2008/11/many-certificates-in-chain-it-just-may.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3925928603549971013/posts/default/5496147434887169221'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3925928603549971013/posts/default/5496147434887169221'/><link rel='alternate' type='text/html' href='http://mauricedechateau.blogspot.com/2008/11/many-certificates-in-chain-it-just-may.html' title='&amp;quot;Too many certificates in chain&amp;quot;? It just may be a corrupt keystore!'/><author><name>Maurice de Chateau</name><uri>https://profiles.google.com/111735333878743353142</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-srAZJqeqcc4/AAAAAAAAAAI/AAAAAAAAAE8/GRJGUoLka70/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3925928603549971013.post-4590611859703908086</id><published>2008-10-31T21:49:00.002+01:00</published><updated>2009-11-25T15:13:06.643+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Security'/><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><title type='text'>An inconsistency between explicit and implicit hashing when signing in Java security?</title><content type='html'>For the connection to a certain other system within our network, the program I'm working on needs to verify that it indeed is what it claims to be: an authorized client. A common way to accomplish is through PKI: it signs the message it sends using a private key, and the other system can verify this signature using the corresponding public key. See e.g. &lt;a href="http://www.developer.com/java/ent/article.php/3092771"&gt;this article&lt;/a&gt; for an explanation of how this works.&lt;br /&gt;&lt;br /&gt;In our case, there are three steps in signing a message:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;calculation of the message digest through a hashing algorithm,&lt;/li&gt;&lt;li&gt;calculation of the digital signature using the private key, and&lt;/li&gt;&lt;li&gt;coding the result to base64.&lt;/li&gt;&lt;/ul&gt;The last step is not part of the normal signing process, but we need to send the result as a string inside an XML message. Using the 'raw' signature would result in weird characters in the XML, very likely choking up the parser.&lt;br /&gt;&lt;br /&gt;As I was coding away, I was lulled into performing each of these steps separately, so I started off with implementing the hashing using the &lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;java.security.MessageDigest&lt;/span&gt;&lt;/span&gt; class. I instantiated it with the "&lt;span style="font-style: italic;"&gt;SHA-1&lt;/span&gt;" algorithm and simply called the &lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;digest &lt;/span&gt;&lt;/span&gt;method with the message to obtain&lt;br /&gt;its hash. Pretty straightforward stuff.&lt;br /&gt;&lt;br /&gt;Then I turned to the &lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;java.security.Signature&lt;/span&gt;&lt;/span&gt; class to supply me with the subsequent signing functionality. It occurred to me that there are algorithm choices that include hashing algorithm names, so I quickly found out that it is possible to let the &lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;Signature&lt;/span&gt;&lt;/span&gt; class take care of&lt;br /&gt;both the first and second step of my signing process. While that struck me as quite convenient, I decided to stick to the original plan and not use the hashing possibility here. I chose the "&lt;span style="font-style: italic;"&gt;NONEwithRSA&lt;/span&gt;" algorithm, and after feeding the message and private key the &lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;sign &lt;/span&gt;&lt;/span&gt;method provided me with an answer.&lt;br /&gt;&lt;br /&gt;Then I encoded it in base64 (using the &lt;a href="http://commons.apache.org/codec/"&gt;Apache Commons Codec library&lt;/a&gt;, which I also could have used for the hashing functionality) and presto! So I thought, at least...&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;But then...&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The first test we performed immediately indicated something was wrong. And after checking everything else (like making sure code page encodings were correct and what not) we came to the conclusion that the signature itself had to be the culprit.&lt;br /&gt;&lt;br /&gt;So I decide to put the 'my' way of creating a signature side by side with the signing method using the implicit hashing possibility, to see whether there might be a difference in the outcome:&lt;br /&gt;&lt;pre class="brush:java"&gt;public void test(byte[] data, PrivateKey privateKey) throws Exception {&lt;br /&gt;   // Explicit hash and separate signing:&lt;br /&gt;   byte[] hashedData = MessageDigest.getInstance("SHA-1").digest(data);&lt;br /&gt;   byte[] signedData = signData(hashedData, privateKey, "NONEwithRSA");&lt;br /&gt;&lt;br /&gt;   // Signing with implicit hashing:&lt;br /&gt;   byte[] signedHashedData = signData(data, privateKey, "SHA1withRSA");&lt;br /&gt;&lt;br /&gt;   System.out.println("Encoded data (explicit hashing) = "&lt;br /&gt;           + new String(Base64.encodeBase64(signedData)));&lt;br /&gt;   System.out.println("Encoded data (implicit hashing) = "&lt;br /&gt;           + new String(Base64.encodeBase64(signedHashedData)));&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;private static byte[] signData(byte[] data, PrivateKey privateKey, String algorithm) throws Exception {&lt;br /&gt;   Signature signature = Signature.getInstance(algorithm);&lt;br /&gt;   signature.initSign(privateKey);&lt;br /&gt;   signature.update(data);&lt;br /&gt;   return signature.sign();&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;And even though:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;from the code it seems that both paths should lead to the same result: no other configuration than the algorithm names are given, so all else should be default, and&lt;br /&gt;&lt;/li&gt;&lt;li&gt;from the &lt;a href="http://java.sun.com/javase/6/docs/technotes/guides/security/StandardNames.html#Signature"&gt;Java security documentation&lt;/a&gt; for the signing options "&lt;span style="font-style: italic;"&gt;NONEwithRSA&lt;/span&gt;" is stated to 'not use a digesting algorithm', so it should act as "&lt;span style="font-style: italic;"&gt;SHA1withRSA&lt;/span&gt;" without the SHA-1 hashing,&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;there definitely is a difference between the outcomes!&lt;br /&gt;&lt;br /&gt;In our situation, the implicit hashing turned out to deliver the correct result (at least, with regards to what the other system expected), so a minimal code change (getting rid of the explicit hashing step) did the trick. We use an external configuration file to set the signing algorithm through a system property, so changing that was easy.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;What's causing this?&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Now why is there a difference between the two approaches? I've tried to find an answer using Google, but that quest didn't turn up any answers.&lt;br /&gt;So I did what any self-respecting developer would do: step through the implementation in a debugger. Unfortunately my toolkit didn't allow me to see everything I wanted to; however I could see that the input of the signing step was identical in both cases and the same implementation for signing is used under the hood (&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;sun.security.rsa.RSACore&lt;/span&gt;&lt;/span&gt;). I cannot see what is happening with respect to internediate padding of the byte arrays, however, so I'm guessing that the 'default' settings of the two approaches - driven by different SignatureSpi implementations - differ in this respect.&lt;br /&gt;&lt;br /&gt;If anyone could point out the actual difference to me, that would be greatly appreciated. For now I'll have to be content with knowing that the two approaches do return different results and that picking one at random may lead to problems...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3925928603549971013-4590611859703908086?l=mauricedechateau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mauricedechateau.blogspot.com/feeds/4590611859703908086/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://mauricedechateau.blogspot.com/2008/10/inconsistency-between-explicit-and.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3925928603549971013/posts/default/4590611859703908086'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3925928603549971013/posts/default/4590611859703908086'/><link rel='alternate' type='text/html' href='http://mauricedechateau.blogspot.com/2008/10/inconsistency-between-explicit-and.html' title='An inconsistency between explicit and implicit hashing when signing in Java security?'/><author><name>Maurice de Chateau</name><uri>https://profiles.google.com/111735333878743353142</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-srAZJqeqcc4/AAAAAAAAAAI/AAAAAAAAAE8/GRJGUoLka70/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3925928603549971013.post-3694920539903353463</id><published>2008-08-24T20:24:00.001+02:00</published><updated>2009-11-25T15:16:52.581+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><title type='text'>When ignorance == bliss doesn't equal TRUE</title><content type='html'>This week I came across some code, the likes of which you probably have seen &lt;i&gt;and&lt;/i&gt; written yourself before. It went something like:&lt;br /&gt;&lt;pre class="brush:java"&gt;public void someMethod(String input) {&lt;br /&gt;  if (input == null || input.length() == 0) {&lt;br /&gt;      return; // Or throw an exception, or...&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  // Other stuff...&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;The &lt;b&gt;if&lt;/b&gt; statement could have been&lt;br /&gt;&lt;pre class="brush:java"&gt;if (input == null || input.equals("")) {&lt;br /&gt;&lt;/pre&gt;or&lt;br /&gt;&lt;pre class="brush:java"&gt;if (input == null || input.isEmpty()) {&lt;br /&gt;&lt;/pre&gt;but these are basically all doing the same, checking the input String for validity: is it there and if so, is it empty?&lt;br /&gt;&lt;br /&gt;There is little wrong with this. Checking input parameters is certainly commendable, as it makes for robust code. But that's not my issue here. That's about doing more work yourself than strictly necessary. As usual if you run into a problem, someone else has encountered the same problem before, solved it and likely published that solution for everybody to use. You just have to know where to find it (or where to look for it).&lt;br /&gt;&lt;br /&gt;The Apache Commons projects have a wealth of solutions for such little problems. The solution appropriate for the check above would be:&lt;br /&gt;&lt;pre class="brush:java"&gt;if (StringUtils.isEmpty(input)) {&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;"That's it?", I hear you say. "You have to include a whole jar and that's all there is to show for (one explicit comparison less, still one method call)"? Well, for this example the answer is 'yes'. And if there is only one location (or just few) in your code you may argue that it's not worth the hassle.&lt;br /&gt;&lt;br /&gt;Now another example that I used myself just the other week. Say you need a String consisting of random characters, but only letters or numbers are allowed, so the range is {'a'...'z', 'A'...'Z', '0'...'9'}. How would you go about it?&lt;br /&gt;I'm sure you could find a solution that is functionally correct, performs well, and may even meet some other requirements thrown in just for the heck of it. Fine, if you have the time and the drive to program such an algorithm yourself, go ahead. But be sure that's an explicit choice, and not the default choice because it's the only way you know of. Consider this code fragment:&lt;br /&gt;&lt;pre class="brush:java"&gt;String random = RandomStringUtils.random(10);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;That is actually all it took for me. Well, I had to include the jar, of course - the same one as the one above, by the way. If you're in a hurry - and who isn't when deadlines are flying by - you want to be aware of such gems.&lt;br /&gt;&lt;br /&gt;So take some time to look around in the Open Source libraries when you're looking for solutions to your everyday problems. You'll be surprised about what's out there, ready for you to (re-)use and probably saving you some significant development time in the process!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3925928603549971013-3694920539903353463?l=mauricedechateau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mauricedechateau.blogspot.com/feeds/3694920539903353463/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://mauricedechateau.blogspot.com/2008/08/when-ignorance-bliss-doesn-equal-true.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3925928603549971013/posts/default/3694920539903353463'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3925928603549971013/posts/default/3694920539903353463'/><link rel='alternate' type='text/html' href='http://mauricedechateau.blogspot.com/2008/08/when-ignorance-bliss-doesn-equal-true.html' title='When ignorance == bliss doesn&amp;#39;t equal TRUE'/><author><name>Maurice de Chateau</name><uri>https://profiles.google.com/111735333878743353142</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-srAZJqeqcc4/AAAAAAAAAAI/AAAAAAAAAE8/GRJGUoLka70/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3925928603549971013.post-4085481041591263572</id><published>2008-08-16T13:18:00.005+02:00</published><updated>2009-11-25T14:45:11.147+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><title type='text'>Blind spot in the Java API: dynamic proxies</title><content type='html'>&lt;span style="font-weight: bold;"&gt;Reflecting on the good ol' days&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Back in the days that the &lt;a href="http://java.sun.com/javase/6/docs/api/java/lang/reflect/package-summary.html"&gt;reflection API&lt;/a&gt; was added to Java, it meant there was a new way to do much of the same, yet in a very generic and nifty way. That came of course at a price: it slowed things down considerably - which was significant as the performance of Java as a whole (language + platform) was still quite an issue at the time.&lt;br /&gt;&lt;br /&gt;In those days I was still working in the Telecom industries, where Java just began to get some foothold. Most of the applications running on the network nodes were still written in C++ (or even plain C) and were simply faster. The powers-that-be decided against the use of reflection (at least in production code) for exactly those performance related reasons and therefore my attention - after a short first impression - shifted away from that API.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Back to the present&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Last week at work I came across some code a co-worker had written and which I was about to use for 'inspiration'.  One class implemented some interface named &lt;a href="http://java.sun.com/javase/6/docs/api/java/lang/reflect/InvocationHandler.html"&gt;InvocationHandler&lt;/a&gt; which I'd never seen before and (obviously) used reflection. I looked it up in the Sun Javadocs and found to my surprise that this interface (along with its partner in crime, the class Proxy) have been around &lt;span style="font-weight: bold;"&gt;since Java 1.3&lt;/span&gt;! That means over eight years - Ouch!&lt;br /&gt;&lt;br /&gt;Ever since I read Scott Meyers books on C++ (yes, &lt;a href="http://www.amazon.com/Effective-Specific-Addison-Wesley-Professional-Computing/dp/0201924889"&gt;this one&lt;/a&gt; in particular) I know there is great advantage in being aware of the available libraries. And even though Scott's remark only seemed to apply to the standard library for C++, I'm sure he meant this in a much wider context. Any engineer should know his tools.&lt;br /&gt;&lt;br /&gt;Knowing all of Java's APIs is another thing altogether, though. The list of classes and interfaces available in the Standard Edition alone seems to be endless, and adding the Enterprise Edition and Micro Edition to the mix makes for a sheer impossible task. I can't imagine there's a soul alive who actually does know about all of them - and knows how to use them in a practical manner, of course.&lt;br /&gt;&lt;br /&gt;It has never been my goal to learn &lt;span style="font-weight: bold;"&gt;all&lt;/span&gt; about the Java APIs, just the parts that I need to write efficient code. But this is one I definetely missed...&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;So what's it all about then?&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;First off, it's called 'proxy' because it allows you to implement the &lt;a href="http://en.wikipedia.org/wiki/Proxy_pattern"&gt;Proxy design pattern&lt;/a&gt; (actually it's not hard to pull off a &lt;a href="http://en.wikipedia.org/wiki/Decorator_pattern"&gt;Decorator&lt;/a&gt; implementation either), and it's called 'dynamic' because it implements a given interface at runtime - and that's where reflection comes into play.&lt;br /&gt;&lt;br /&gt;This is the 'classic' Proxy pattern:&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_btTA3f1LngM/SKncxdMeUcI/AAAAAAAAABw/pFtx9qp1r6Q/s1600-h/Proxy.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://3.bp.blogspot.com/_btTA3f1LngM/SKncxdMeUcI/AAAAAAAAABw/pFtx9qp1r6Q/s320/Proxy.png" alt="Proxy pattern" id="BLOGGER_PHOTO_ID_5235958784003559874" border="0" /&gt;&lt;/a&gt;A dynamic proxy doesn't have the compile time relationship with the interface. As said, this relationship is forged at runtime. The code for such a class might look something like this:&lt;br /&gt;&lt;pre class="brush:java"&gt;package server;&lt;br /&gt;&lt;br /&gt;import java.lang.reflect.*;&lt;br /&gt;&lt;br /&gt;public class DynamicProxy implements InvocationHandler {&lt;br /&gt;    private Object realSubject;&lt;br /&gt;&lt;br /&gt;    public DynamicProxy(Object realSubject) {&lt;br /&gt;        this.realSubject = realSubject;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public Object invoke(Object proxy, Method method, Object[] args)&lt;br /&gt;        throws Throwable {&lt;br /&gt;        System.out.println("Before the call...");&lt;br /&gt;        Object result = method.invoke(realSubject, args);&lt;br /&gt;        System.out.println("...after the call.");&lt;br /&gt;        return result;&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;Of course you may want to insert something more useful before and after the method invocation in a practical case...&lt;br /&gt;&lt;br /&gt;Now all one needs is the means to let the client get a reference to a &lt;span style="font-size:85%;"&gt;&lt;span style="font-family: courier new;"&gt;Subject&lt;/span&gt;&lt;/span&gt; in a way that doesn't reveal the dynamic proxy. A factory, which normally may just hide the implementation class and/or static proxy from the client, could be 'upgraded' to do just that:&lt;br /&gt;&lt;pre class="brush:java"&gt;package server;&lt;br /&gt;&lt;br /&gt;import java.lang.reflect.Proxy;&lt;br /&gt;&lt;br /&gt;public class SubjectFactory {&lt;br /&gt;    public static Subject getSubjectInstance() {&lt;br /&gt;        return (Subject) Proxy.newProxyInstance(RealSubject.class&lt;br /&gt;            .getClassLoader(), new Class[] { Subject.class },&lt;br /&gt;            new DynamicProxy(new RealSubject()));&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;Notice how:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;the classloader of the implementation class is given as the first argument&lt;/li&gt;&lt;li&gt;the &lt;span style="font-size:85%;"&gt;&lt;span style="font-family: courier new;"&gt;Subject&lt;/span&gt;&lt;/span&gt; interface is entered as the second parameter; in fact all (distinct) interfaces implemented by the implementation class may be given here, so &lt;span style="font-size:85%;"&gt;&lt;span style="font-family: courier new;"&gt;RealSubject.&lt;span style="font-weight: bold;"&gt;class&lt;/span&gt;.getInterfaces()&lt;/span&gt;&lt;/span&gt; would be fine too&lt;/li&gt;&lt;li&gt; the &lt;span style="font-size:85%;"&gt;&lt;span style="font-family: courier new;"&gt;DynamicProxy&lt;/span&gt;&lt;/span&gt; is instantiated given a &lt;span style="font-size:85%;"&gt;&lt;span style="font-family: courier new;"&gt;RealSubject&lt;/span&gt;&lt;/span&gt; instance; this is the instance on which the actual invocation is performed&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;And this is what the class diagram has become:&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_btTA3f1LngM/SKnmQqm_gBI/AAAAAAAAAB4/yQPi2FZgD4Q/s1600-h/DynamicProxy.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://1.bp.blogspot.com/_btTA3f1LngM/SKnmQqm_gBI/AAAAAAAAAB4/yQPi2FZgD4Q/s320/DynamicProxy.png" alt="Dynamic Proxy with Factory" id="BLOGGER_PHOTO_ID_5235969215785041938" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;The definitions of the &lt;span style="font-size:85%;"&gt;&lt;span style="font-family: courier new;"&gt;Client&lt;/span&gt;&lt;/span&gt; and &lt;span style="font-size:85%;"&gt;&lt;span style="font-family: courier new;"&gt;ServerImpl&lt;/span&gt;&lt;/span&gt; classes and &lt;span style="font-size:85%;"&gt;&lt;span style="font-family: courier new;"&gt;Server&lt;/span&gt;&lt;/span&gt; interface haven't changed at all if a factory was used in the first place. So this little mechanism can be used to insert any pre- and post-processing you need at any time, e.g. to surround the call with session or transaction management.&lt;br /&gt;&lt;br /&gt;Now do I hear someone say AOP? This construct actually predates &lt;a href="http://www.eclipse.org/aspectj/"&gt;AspectJ&lt;/a&gt;, and I guess that if you don't need all of the versatility of such a framework, it's good to know this tool is in your standard toolkit!&lt;br /&gt;&lt;br /&gt;If this short intro has grabbed your interest, you may want to go on reading &lt;a href="http://www.javaworld.com/javaworld/jw-11-2000/jw-1110-proxy.html"&gt;this old Javaworld article&lt;/a&gt; about dynamic proxies to get your feet wet a little more...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3925928603549971013-4085481041591263572?l=mauricedechateau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mauricedechateau.blogspot.com/feeds/4085481041591263572/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://mauricedechateau.blogspot.com/2008/08/blind-spot-in-java-api-dynamic-proxies.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3925928603549971013/posts/default/4085481041591263572'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3925928603549971013/posts/default/4085481041591263572'/><link rel='alternate' type='text/html' href='http://mauricedechateau.blogspot.com/2008/08/blind-spot-in-java-api-dynamic-proxies.html' title='Blind spot in the Java API: dynamic proxies'/><author><name>Maurice de Chateau</name><uri>https://profiles.google.com/111735333878743353142</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-srAZJqeqcc4/AAAAAAAAAAI/AAAAAAAAAE8/GRJGUoLka70/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_btTA3f1LngM/SKncxdMeUcI/AAAAAAAAABw/pFtx9qp1r6Q/s72-c/Proxy.png' height='72' width='72'/><thr:total>0</thr:total></entry></feed>
