[[dynamic_classloading]]
== Dynamic classloading

In most applications, the business logic and packagers are available in
the classpath, but there are situations where you need to apply a hot
patch such as adding a new field packager, or an ISO filter, so we
have provided this dynamic class loading capabilities.

If you know OSGi you can laugh as much as we do with our limited
poor-man implementation, it has many drawbacks that we'll explain
below, but if you need to apply a hot patch until you can bounce the
system and restart with a new build, you can appreciate that our
dynamic classloading has some use.

In addition to the +deploy+ directory that Q2 monitors to see changes
in the deployed services, it also monitors the timestamp of the 
+deploy/lib+ directory, and if changed, it scans all jars in there
and add them to the URL classloader of the MBeanServer, used by
Q2 to instantiate its QBeans.

[TIP]
=====
The previous paragraph basically tells you all you need to know about
jPOS' Q2 dynamic classloading. If you read it again, and understand
every word, then you can skip to the next section. If you have doubts,
we'll try to clarify them below.
=====

Let's try a simple example. If you start Q2 in say the +/opt/local/jpos+
directory, it will be monitoring the +/opt/local/jpos/deploy+ directory
for QBean descriptors and the +/opt/local/jpos/deploy/lib+ for jars
to be added to the classpath.

At start up the output will look like this:

----
<log realm="Q2.system">
  <info>
    Q2 started, deployDir=/opt/local/jpos/deploy
    ...
    ...
  </info>
</log>
----

If while Q2 is running you create a +lib+ directory inside +deploy+, 
you'll see a message like this:

----
<log realm="Q2.system">
  <info>
    new classloader [58f0fa12] has been created
  </info>
</log>
----

If you then place a jar inside that new +lib+ directory, **and you touch**
+lib+ directory so that it changes its timestamp, you'll see once again
the message indicating that a new classloader has been created, but this
time, it will contain your new jar.

[NOTE]
======
If the +deploy/lib+ directory is available, with jars in it,
at Q2 start up time, it will of course be picked up.
======

The 'and you touch' part mentioned above is important, because Q2 doesn't
monitor the jars inside the lib directory, it monitors the timestamp
of the +deploy/lib+ directory itself. This gives us some kind of poor
man ability to deploy several jars in an atomic way (to manually solve
dependencies).

So now that the new jar is available in the classpath, you can deploy
your QBean by adding its xml QBean descriptor in the +deploy+ dir.

[float]
=== Dynamically deploying QTest 

If you've followed the instructions in <<qtest>>, you can copy
+build/libs/qtest-1.0.0.jar+ generated using +gradle jar+ into
another jPOS Q2 system (i.e. you could use the default jPOS distro
clone) and follow the previous instructions to run it.

In addition to that, Q2 support remote dynamic classloading, so instead
of placing your jar in the +deploy/lib+, you could load it from a remote
URL.

For your convenience, we've placed a compiled version of qtest in the
following URL: +http://us.jpos.org/private/qtest-1.0.0.jar+, so you
can deploy in any Q2 system the following QBean:

[source,xml]
----
<qbean name='qtest' class='org.jpos.qtest.QTest' logger='Q2'>
  <classpath>
    <url>http://us.jpos.org/examples/qtest-1.0.0.jar</url>
  </classpath>
</qbean>
----

A QBean can download its supporting classes from multiple URLs, the
previous example could read:

[source,xml]
----
<qbean name='qtest' class='org.jpos.qtest.QTest' logger='Q2'>
  <classpath>
    <url>http://us.jpos.org/examples/qtest-1.0.0.jar</url>
    <url>http://myhost.mydomain.com/another-dependency.jar</url>
    ...
  </classpath>
</qbean>
----

[TIP]
=====
jPOS applications are usually mission critical and highly
sensitive, so in most situations, it's not a very good idea to 
download the implementation from remote sites.

But on a local DMZ where you have many nodes using the same code,
it can come very handy to use this feature and download code from
a local artifact server.
=====

