[jboss-cvs] JBossAS SVN: r101610 - in projects/jboss-jca/trunk: embedded/src/main/java/org/jboss/jca/embedded and 4 other directories.

jboss-cvs-commits at lists.jboss.org jboss-cvs-commits at lists.jboss.org
Sat Feb 27 20:38:30 EST 2010


Author: jesper.pedersen
Date: 2010-02-27 20:38:28 -0500 (Sat, 27 Feb 2010)
New Revision: 101610

Added:
   projects/jboss-jca/trunk/fungal/src/main/java/org/jboss/jca/fungal/impl/HotDeployer.java
   projects/jboss-jca/trunk/fungal/src/main/java/org/jboss/jca/fungal/impl/HotDeployerMBean.java
Modified:
   projects/jboss-jca/trunk/doc/developerguide/en/modules/fungal.xml
   projects/jboss-jca/trunk/embedded/src/main/java/org/jboss/jca/embedded/EmbeddedJCA.java
   projects/jboss-jca/trunk/fungal/src/main/java/org/jboss/jca/fungal/api/KernelConfiguration.java
   projects/jboss-jca/trunk/fungal/src/main/java/org/jboss/jca/fungal/impl/KernelImpl.java
   projects/jboss-jca/trunk/fungal/src/main/java/org/jboss/jca/fungal/impl/remote/Communication.java
   projects/jboss-jca/trunk/fungal/src/main/java/org/jboss/jca/fungal/impl/remote/CommunicationServer.java
   projects/jboss-jca/trunk/sjc/src/main/java/org/jboss/jca/sjc/Main.java
Log:
[JBJCA-293] Hot deployer

Modified: projects/jboss-jca/trunk/doc/developerguide/en/modules/fungal.xml
===================================================================
--- projects/jboss-jca/trunk/doc/developerguide/en/modules/fungal.xml	2010-02-27 22:27:22 UTC (rev 101609)
+++ projects/jboss-jca/trunk/doc/developerguide/en/modules/fungal.xml	2010-02-28 01:38:28 UTC (rev 101610)
@@ -30,6 +30,9 @@
           Deployer framework
         </listitem>
         <listitem>
+          Hot deployment
+        </listitem>
+        <listitem>
           Communication protocol
         </listitem>
         <listitem>
@@ -44,22 +47,69 @@
     <section id="fungal_configuration">
       <title>Configuration</title>
 
+      <para>The kernel is configured through the</para>
+      <programlisting>
+org.jboss.jca.fungal.api.KernelConfiguration
+      </programlisting>
+
+      <para>class, which allows the developer to configure the kernel
+        in the most optimal way for the container configuration.</para>
+
+      <para>It is a best practice to give the configuration a name using the
+        <code>name</code> method, otherwise the kernel will use the default
+        name of <code>fungal</code>.</para>
+
+      <para>Based on the kernel configuration a number of system properties are
+        set</para>
+
+      <table frame="all">
+        <title>Kernel system properties</title>
+        <tgroup cols="2" align="left" colsep="1" rowsep="1">
+          <colspec colname="c1"/>
+          <colspec colname="c2" colwidth="3*"/>
+          <thead>
+            <row>
+              <entry align="left">Name</entry>
+              <entry align="left">Description</entry>
+            </row>
+          </thead>
+          <tbody>
+            <row>
+              <entry>&lt;name&gt;.home</entry>
+              <entry>The root of the container configuration</entry>
+            </row>
+            <row>
+              <entry>&lt;name&gt;.bindaddress</entry>
+              <entry>The network bind address of the container configuration</entry>
+            </row>
+          </tbody>
+        </tgroup>
+      </table>
+
+      <para>Furthermore, the kernel makes use the Java system property <code>java.io.tmpdir</code>
+        for temporary files if needed.</para>
+
+    </section>
+
+    <section id="fungal_booting">
+      <title>Booting the kernel</title>
+
       <para>The kernel is booted using a</para>
       <programlisting>
-$JBOSS_JCA_HOME/config/bootstrap.xml
+${&lt;name&gt;.home}/config/bootstrap.xml
       </programlisting>
 
       <para>file, where references to URLs for bean deployments.</para>
 
       <para>The layout of bootstrap.xml is defined in</para>
       <programlisting>
-$JBOSS_JCA_HOME/config/bootstrap.xsd
+${&lt;name&gt;.home}/config/bootstrap.xsd
       </programlisting>
 
       <para>The</para>
 
       <programlisting>
-$JBOSS_JCA_HOME/config/deployment.xsd
+${&lt;name&gt;.home}/config/deployment.xsd
       </programlisting>
 
       <para>file defines how bean deployments are constructed.</para>
@@ -135,12 +185,12 @@
         </listitem>
       </itemizedlist>
 
-      <para>In order to define locations relative to the install root of the JBoss JCA
-        container the variable</para>
+      <para>In order to define locations relative to the install root of the Fungal
+        container configuration the variable</para>
       <programlisting>
-${jboss.jca.home}
+${&lt;name&gt;.home}
       </programlisting>
-      <para>can be used.</para>
+      <para>can be used. An example would be <code>${jboss.jca.home}</code>.</para>
 
       <para>There is support for accessing system properties using the "${property}" mechanism
         with an optional default value</para>
@@ -272,9 +322,14 @@
       <para>Furthermore the dependencies between beans are recorded in order to be able to safely shutdown
         deployments.</para>
 
-      <para>Note, that all deployment units in the <code>deploy</code> directory are booted in sequence
-        defined by the <code>File.listFiles()</code> method.</para>
+      <para>The Fungal kernel can deploy the archives in the <code>deploy</code> directory in parallel if specified
+        by the <code>KernelConfiguration.parallelDeploy()</code> method. Otherwise are all the deployment units
+        booted in sequence as defined by the <code>File.listFiles()</code> method.</para>
 
+      <para>The Fungal kernel features a hot deployer, which scans the deployment directory at the specified
+        intervals for new, changed or removed deployment units. The properties of the hot deployer can
+        be controlled through the <code>KernelConfiguration</code> object or through JMX.</para>
+
     </section>
 
     <section id="fungal_classloading">
@@ -536,7 +591,9 @@
 
 // Create a kernel configuration and start the kernel
 KernelConfiguration kernelConfiguration = new KernelConfiguration();
+kernelConfiguration = kernelConfiguration.name("jboss.jca");
 kernelConfiguration = kernelConfiguration.remoteAccess(false);
+kernelConfiguration = kernelConfiguration.hotDeployment(false);
 
 Kernel kernel = KernelFactory.create(kernelConfiguration);
 kernel.startup();

Modified: projects/jboss-jca/trunk/embedded/src/main/java/org/jboss/jca/embedded/EmbeddedJCA.java
===================================================================
--- projects/jboss-jca/trunk/embedded/src/main/java/org/jboss/jca/embedded/EmbeddedJCA.java	2010-02-27 22:27:22 UTC (rev 101609)
+++ projects/jboss-jca/trunk/embedded/src/main/java/org/jboss/jca/embedded/EmbeddedJCA.java	2010-02-28 01:38:28 UTC (rev 101610)
@@ -81,7 +81,10 @@
    public void startup() throws Throwable
    {
       KernelConfiguration kernelConfiguration = new KernelConfiguration();
+      kernelConfiguration = kernelConfiguration.name("jboss.jca");
+      kernelConfiguration = kernelConfiguration.parallelDeploy(false);
       kernelConfiguration = kernelConfiguration.remoteAccess(false);
+      kernelConfiguration = kernelConfiguration.hotDeployment(false);
 
       kernel = KernelFactory.create(kernelConfiguration);
       kernel.startup();

Modified: projects/jboss-jca/trunk/fungal/src/main/java/org/jboss/jca/fungal/api/KernelConfiguration.java
===================================================================
--- projects/jboss-jca/trunk/fungal/src/main/java/org/jboss/jca/fungal/api/KernelConfiguration.java	2010-02-27 22:27:22 UTC (rev 101609)
+++ projects/jboss-jca/trunk/fungal/src/main/java/org/jboss/jca/fungal/api/KernelConfiguration.java	2010-02-28 01:38:28 UTC (rev 101610)
@@ -1,6 +1,6 @@
 /*
  * JBoss, Home of Professional Open Source.
- * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * Copyright 2009-2010, Red Hat Middleware LLC, and individual contributors
  * as indicated by the @author tags. See the copyright.txt file in the
  * distribution for a full listing of individual contributors.
  *
@@ -30,9 +30,24 @@
  */
 public class KernelConfiguration
 {
+   /** Name */
+   private String name;
+
    /** Home */
    private URL home;
 
+   /** Library */
+   private String library;
+
+   /** Configuration */
+   private String configuration;
+
+   /** Deploy */
+   private String deploy;
+
+   /** Do parallel deployment in deploy */
+   private boolean parallelDeploy;
+
    /** Bind address */
    private String bindAddress;
 
@@ -45,20 +60,54 @@
    /** Remote port */
    private int remotePort;
 
+   /** Hot deployment */
+   private boolean hotDeployment;
+
+   /** Hot deployment internal in seconds */
+   private int hotDeploymentInterval;
+
    /**
     * Constructor
     */
    public KernelConfiguration()
    {
+      name = "fungal";
       home = null;
+      library = "lib";
+      configuration = "config";
+      deploy = "deploy";
+      parallelDeploy = true;
       bindAddress = null;
       threadGroup = null;
       remoteAccess = true;
       remotePort = 1202;
+      hotDeployment = true;
+      hotDeploymentInterval = 5;
    }
 
    /**
-    * Set the home
+    * Set the name; default <code>fungal</code>
+    * @param n The name
+    * @return The configuration
+    */
+   public KernelConfiguration name(String n)
+   {
+      this.name = n;
+
+      return this;
+   }
+
+   /**
+    * Get the name
+    * @return The name
+    */
+   public String getName()
+   {
+      return name;
+   }
+
+   /**
+    * Set the home; default <code>null</code>
     * @param h The home
     * @return The configuration
     */
@@ -79,7 +128,93 @@
    }
 
    /**
-    * Set the bind address
+    * Set the library directory; default <code>lib</code>
+    * @param value The value
+    * @return The configuration
+    */
+   public KernelConfiguration library(String value)
+   {
+      this.library = value;
+
+      return this;
+   }
+
+   /**
+    * Get the library directory
+    * @return The value
+    */
+   public String getLibrary()
+   {
+      return library;
+   }
+
+   /**
+    * Set the configuration directory; default <code>config</code>
+    * @param value The value
+    * @return The configuration
+    */
+   public KernelConfiguration configuration(String value)
+   {
+      this.configuration = value;
+
+      return this;
+   }
+
+   /**
+    * Get the configuration directory
+    * @return The value
+    */
+   public String getConfiguration()
+   {
+      return configuration;
+   }
+
+   /**
+    * Set the deploy directory; default <code>deploy</code>
+    * @param value The value
+    * @return The configuration
+    */
+   public KernelConfiguration deploy(String value)
+   {
+      this.deploy = value;
+
+      return this;
+   }
+
+   /**
+    * Get the deploy directory
+    * @return The value
+    */
+   public String getDeploy()
+   {
+      return deploy;
+   }
+
+   /**
+    * Set if the files in the deploy directory should deployed
+    * in parallel; default <code>true</code>
+    * @param value The value
+    * @return The configuration
+    */
+   public KernelConfiguration parallelDeploy(boolean value)
+   {
+      this.parallelDeploy = value;
+
+      return this;
+   }
+
+   /**
+    * Get if the files in the deploy directpry should be deployed
+    * in parallel
+    * @return The value
+    */
+   public boolean isParallelDeploy()
+   {
+      return parallelDeploy;
+   }
+
+   /**
+    * Set the bind address; default <code>null</code>
     * @param ba The value
     * @return The configuration
     */
@@ -100,7 +235,7 @@
    }
 
    /**
-    * Set the thread group
+    * Set the thread group; default <code>null</code>
     * @param tg The value
     * @return The configuration
     */
@@ -121,7 +256,7 @@
    }
 
    /**
-    * Set the remote access
+    * Set the remote access; default <code>true</code>
     * @param v The value
     * @return The configuration
     */
@@ -142,7 +277,7 @@
    }
 
    /**
-    * Set the port for remote access
+    * Set the port for remote access; default <code>1202</code>
     * @param v The value
     * @return The configuration
     */
@@ -161,4 +296,46 @@
    {
       return remotePort;
    }
+
+   /**
+    * Set the hot deployment; default <code>true</code>
+    * @param v The value
+    * @return The configuration
+    */
+   public KernelConfiguration hotDeployment(boolean v)
+   {
+      this.hotDeployment = v;
+
+      return this;
+   }
+
+   /**
+    * Is hot deployment enabled ?
+    * @return The value
+    */
+   public boolean isHotDeployment()
+   {
+      return hotDeployment;
+   }
+
+   /**
+    * Set the interval in seconds for hot deployment; default <code>5</code>
+    * @param v The value
+    * @return The configuration
+    */
+   public KernelConfiguration hotDeploymentInterval(int v)
+   {
+      this.hotDeploymentInterval = v;
+
+      return this;
+   }
+
+   /**
+    * Get the hot deployment interval in seconds
+    * @return The value
+    */
+   public int getHotDeploymentInterval()
+   {
+      return hotDeploymentInterval;
+   }
 }

Added: projects/jboss-jca/trunk/fungal/src/main/java/org/jboss/jca/fungal/impl/HotDeployer.java
===================================================================
--- projects/jboss-jca/trunk/fungal/src/main/java/org/jboss/jca/fungal/impl/HotDeployer.java	                        (rev 0)
+++ projects/jboss-jca/trunk/fungal/src/main/java/org/jboss/jca/fungal/impl/HotDeployer.java	2010-02-28 01:38:28 UTC (rev 101610)
@@ -0,0 +1,410 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008-2009, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.jca.fungal.impl;
+
+import java.lang.reflect.Method;
+import java.io.File;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.Future;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+/**
+ * The hot deployer for JBoss JCA/Fungal
+ * @author <a href="mailto:jesper.pedersen at jboss.org">Jesper Pedersen</a>
+ */
+public final class HotDeployer implements HotDeployerMBean, Runnable
+{
+   private int interval;
+   private File directory;
+   private KernelImpl kernel;
+
+   private AtomicBoolean running;
+   private List<URL> deployments;
+   private Map<URL, Long> modifiedTimestamp;
+
+   /** Logging */
+   private static Object logging;
+
+   /**
+    * Constructor
+    * @param interval The scan interval in seconds
+    * @param directory The directory that should be scanned
+    * @param kernel The kernel
+    */
+   public HotDeployer(int interval, File directory, KernelImpl kernel)
+   {
+      if (interval <= 0)
+         throw new IllegalArgumentException("Internal is invalid");
+
+      if (directory == null)
+         throw new IllegalArgumentException("Directory is null");
+
+      if (kernel == null)
+         throw new IllegalArgumentException("Kernel is null");
+
+      this.interval = interval;
+      this.directory = directory;
+      this.kernel = kernel;
+      this.running = new AtomicBoolean(false);
+      this.deployments = new ArrayList<URL>();
+      this.modifiedTimestamp = new HashMap<URL, Long>();
+
+      if (logging == null)
+         initLogging(kernel.getKernelClassLoader());
+   }
+
+   /**
+    * Register deployment
+    * @param deployment The deployment
+    */
+   public void register(URL deployment)
+   {
+      if (deployment == null)
+         throw new IllegalArgumentException("Deployment is null");
+
+      deployments.add(deployment);
+
+      try
+      {
+         File f = new File(deployment.toURI());
+         modifiedTimestamp.put(deployment, Long.valueOf(f.lastModified()));
+      }
+      catch (URISyntaxException use)
+      {
+         // Ignore
+      }
+   }
+
+   /**
+    * Unregister deployment
+    * @param deployment The deployment
+    */
+   public void unregister(URL deployment)
+   {
+      if (deployment == null)
+         throw new IllegalArgumentException("Deployment is null");
+
+      deployments.remove(deployment);
+      modifiedTimestamp.remove(deployment);
+   }
+
+   /**
+    * Get the interval in seconds
+    * @return The value
+    */
+   public int getInterval()
+   {
+      return interval;
+   }
+
+   /**
+    * Set the interval
+    * @param value The value in seconds
+    */
+   public void setInterval(int value)
+   {
+      this.interval = value;
+   }
+
+   /**
+    * Start
+    */
+   public void start()
+   {
+      running.set(true);
+      
+      Future<?> f = kernel.getExecutorService().submit(this);
+   }
+
+   /**
+    * Stop
+    */
+   public void stop()
+   {
+      running.set(false);
+   }
+
+   /**
+    * Run
+    */
+   public void run()
+   {
+      while (running.get())
+      {
+         long start = System.currentTimeMillis();
+         try
+         {
+            List<URL> removeDeployments = new ArrayList<URL>(deployments);
+            List<URL> changedDeployments = null;
+            List<URL> newDeployments = null;
+
+            File[] files = directory.listFiles();
+
+            for (File f : files)
+            {
+               URL url = f.toURI().toURL();
+               if (removeDeployments.contains(url))
+               {
+                  long modified = modifiedTimestamp.get(url).longValue();
+
+                  if (f.lastModified() == modified)
+                  {
+                     removeDeployments.remove(url);
+                  }
+                  else
+                  {
+                     if (changedDeployments == null)
+                        changedDeployments = new ArrayList<URL>(1);
+
+                     changedDeployments.add(url);
+                  }
+               }
+               else
+               {
+                  if (newDeployments == null)
+                     newDeployments = new ArrayList<URL>(1);
+
+                  newDeployments.add(url);
+               }
+            }
+
+            if (removeDeployments.size() > 0)
+            {
+               for (URL url : removeDeployments)
+               {
+                  try
+                  {
+                     unregister(url);
+                     kernel.getMainDeployer().undeploy(url);
+                  }
+                  catch (Throwable undeploy)
+                  {
+                     error(undeploy.getMessage(), undeploy);
+                  }
+               }
+            }
+
+            if (changedDeployments != null)
+            {
+               for (URL url : changedDeployments)
+               {
+                  try
+                  {
+                     unregister(url);
+                     kernel.getMainDeployer().undeploy(url);
+
+                     register(url);
+                     kernel.getMainDeployer().deploy(url);
+                  }
+                  catch (Throwable deploy)
+                  {
+                     error(deploy.getMessage(), deploy);
+                  }
+               }
+            }
+
+            if (newDeployments != null)
+            {
+               for (URL url : newDeployments)
+               {
+                  try
+                  {
+                     register(url);
+                     kernel.getMainDeployer().deploy(url);
+                  }
+                  catch (Throwable deploy)
+                  {
+                     error(deploy.getMessage(), deploy);
+                  }
+               }
+            }
+            
+            long took = System.currentTimeMillis() - start;
+            long sleep = interval * 1000L - took;
+
+            if (sleep <= 10)
+               sleep = 10;
+
+            Thread.currentThread().sleep(sleep);
+         }
+         catch (Throwable t)
+         {
+            error(t.getMessage(), t);
+         }
+      }
+   }
+
+   /**
+    * Init logging
+    */
+   @SuppressWarnings("unchecked") 
+   private static void initLogging(ClassLoader cl)
+   {
+      try
+      {
+         Class clz = Class.forName("org.jboss.logging.Logger", true, cl);
+         
+         Method mGetLogger = clz.getMethod("getLogger", String.class);
+
+         logging = mGetLogger.invoke((Object)null, new Object[] {"org.jboss.jca.fungal.impl.HotDeployer"});
+      }
+      catch (Throwable t)
+      {
+         // Nothing we can do
+      }
+   }
+
+   /**
+    * Logging: ERROR
+    * @param s The string
+    * @param t The throwable
+    */
+   @SuppressWarnings("unchecked") 
+   private void error(String s, Throwable t)
+   {
+      if (logging != null)
+      {
+         try
+         {
+            Class clz = logging.getClass();
+            Method mError = clz.getMethod("error", Object.class, Throwable.class);
+            mError.invoke(logging, new Object[] {s, t});
+         }
+         catch (Throwable th)
+         {
+            // Nothing we can do
+         }
+      }
+      else
+      {
+         System.out.println(s);
+         t.printStackTrace(System.out);
+      }
+   }
+
+   /**
+    * Logging: WARN
+    * @param s The string
+    */
+   @SuppressWarnings("unchecked") 
+   private void warn(String s)
+   {
+      if (logging != null)
+      {
+         try
+         {
+            Class clz = logging.getClass();
+            Method mWarn = clz.getMethod("warn", Object.class);
+            mWarn.invoke(logging, new Object[] {s});
+         }
+         catch (Throwable t)
+         {
+            // Nothing we can do
+         }
+      }
+      else
+      {
+         System.out.println(s);
+      }
+   }
+
+   /**
+    * Logging: INFO
+    * @param s The string
+    */
+   @SuppressWarnings("unchecked") 
+   private void info(String s)
+   {
+      if (logging != null)
+      {
+         try
+         {
+            Class clz = logging.getClass();
+            Method mInfo = clz.getMethod("info", Object.class);
+            mInfo.invoke(logging, new Object[] {s});
+         }
+         catch (Throwable t)
+         {
+            // Nothing we can do
+         }
+      }
+      else
+      {
+         System.out.println(s);
+      }
+   }
+
+   /**
+    * Logging: Is DEBUG enabled
+    * @return True if debug is enabled; otherwise false
+    */
+   @SuppressWarnings("unchecked") 
+   private boolean isDebugEnabled()
+   {
+      if (logging != null)
+      {
+         try
+         {
+            Class clz = logging.getClass();
+            Method mIsDebugEnabled = clz.getMethod("isDebugEnabled", (Class[])null);
+            return ((Boolean)mIsDebugEnabled.invoke(logging, (Object[])null)).booleanValue();
+         }
+         catch (Throwable t)
+         {
+            // Nothing we can do
+         }
+      }
+      return true;
+   }
+
+   /**
+    * Logging: DEBUG
+    * @param s The string
+    */
+   @SuppressWarnings("unchecked") 
+   private void debug(String s)
+   {
+      if (logging != null)
+      {
+         try
+         {
+            Class clz = logging.getClass();
+            Method mDebug = clz.getMethod("debug", Object.class);
+            mDebug.invoke(logging, new Object[] {s});
+         }
+         catch (Throwable t)
+         {
+            // Nothing we can do
+         }
+      }
+      else
+      {
+         System.out.println(s);
+      }
+   }
+}

Added: projects/jboss-jca/trunk/fungal/src/main/java/org/jboss/jca/fungal/impl/HotDeployerMBean.java
===================================================================
--- projects/jboss-jca/trunk/fungal/src/main/java/org/jboss/jca/fungal/impl/HotDeployerMBean.java	                        (rev 0)
+++ projects/jboss-jca/trunk/fungal/src/main/java/org/jboss/jca/fungal/impl/HotDeployerMBean.java	2010-02-28 01:38:28 UTC (rev 101610)
@@ -0,0 +1,52 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008-2009, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.jca.fungal.impl;
+
+/**
+ * The hot deployer MBean for JBoss JCA/Fungal
+ * @author <a href="mailto:jesper.pedersen at jboss.org">Jesper Pedersen</a>
+ */
+public interface HotDeployerMBean
+{
+   /**
+    * Get the interval in seconds
+    * @return The value
+    */
+   public int getInterval();
+
+   /**
+    * Set the interval
+    * @param value The value in seconds
+    */
+   public void setInterval(int value);
+
+   /**
+    * Start
+    */
+   public void start();
+
+   /**
+    * Stop
+    */
+   public void stop();
+}

Modified: projects/jboss-jca/trunk/fungal/src/main/java/org/jboss/jca/fungal/impl/KernelImpl.java
===================================================================
--- projects/jboss-jca/trunk/fungal/src/main/java/org/jboss/jca/fungal/impl/KernelImpl.java	2010-02-27 22:27:22 UTC (rev 101609)
+++ projects/jboss-jca/trunk/fungal/src/main/java/org/jboss/jca/fungal/impl/KernelImpl.java	2010-02-28 01:38:28 UTC (rev 101610)
@@ -65,7 +65,7 @@
 public class KernelImpl implements Kernel
 {
    /** Version information */
-   private static final String VERSION = "Fungal 0.5.1";
+   private static final String VERSION = "Fungal 0.6";
 
    /** Kernel configuration */
    private KernelConfiguration kernelConfiguration;
@@ -115,6 +115,9 @@
    /** Callback beans */
    private ConcurrentMap<Object, List<Callback>> callbackBeans = new ConcurrentHashMap<Object, List<Callback>>();
 
+   /** Hot deployer */
+   private HotDeployer hotDeployer;
+
    /** Logging */
    private Object logging;
 
@@ -127,6 +130,7 @@
       this.kernelConfiguration = kc;
       this.beanDeployments = new AtomicInteger(0);
       this.temporaryEnvironment = false;
+      this.hotDeployer = null;
    }
 
    /**
@@ -164,12 +168,12 @@
       if (kernelConfiguration.getHome() != null)
       {
          root = new File(kernelConfiguration.getHome().toURI());
-         SecurityActions.setSystemProperty("jboss.jca.home", root.getAbsolutePath());
+         SecurityActions.setSystemProperty(kernelConfiguration.getName() + ".home", root.getAbsolutePath());
       }
       else
       {
          File tmp = new File(SecurityActions.getSystemProperty("java.io.tmpdir"));
-         root = new File(tmp, "jboss-jca");
+         root = new File(tmp, kernelConfiguration.getName());
 
          if (root.exists())
          {
@@ -179,7 +183,7 @@
          if (!root.mkdirs())
             throw new IOException("Could not create directory " + root.getAbsolutePath());
 
-         SecurityActions.setSystemProperty("jboss.jca.home", root.getAbsolutePath());
+         SecurityActions.setSystemProperty(kernelConfiguration.getName() + ".home", root.getAbsolutePath());
          
          temporaryEnvironment = true;
       }
@@ -190,9 +194,9 @@
 
       if (root != null && root.exists())
       {
-         libDirectory = new File(root, File.separator + "lib" + File.separator);
-         configDirectory = new File(root, File.separator + "config" + File.separator);
-         deployDirectory = new File(root, File.separator + "deploy" + File.separator);
+         libDirectory = new File(root, File.separator + kernelConfiguration.getLibrary() + File.separator);
+         configDirectory = new File(root, File.separator + kernelConfiguration.getConfiguration() + File.separator);
+         deployDirectory = new File(root, File.separator + kernelConfiguration.getDeploy() + File.separator);
       }
 
       oldClassLoader = SecurityActions.getThreadContextClassLoader();
@@ -211,17 +215,20 @@
                                         "com.sun.xml.internal.stream.XMLInputFactoryImpl");
 
       if (kernelConfiguration.getBindAddress() != null)
-         SecurityActions.setSystemProperty("jboss.jca.bindaddress", kernelConfiguration.getBindAddress().trim());
+      {
+         SecurityActions.setSystemProperty(kernelConfiguration.getName() + ".bindaddress", 
+                                           kernelConfiguration.getBindAddress().trim());
+      }
 
       // Init logging
       initLogging(kernelClassLoader);
 
       // Create MBeanServer
-      mbeanServer = MBeanServerFactory.createMBeanServer("jboss.jca");
+      mbeanServer = MBeanServerFactory.createMBeanServer(kernelConfiguration.getName());
 
       // Main deployer
       mainDeployer = new MainDeployerImpl(this);
-      ObjectName mainDeployerObjectName = new ObjectName("jboss.jca:name=MainDeployer");
+      ObjectName mainDeployerObjectName = new ObjectName(kernelConfiguration.getName() + ":name=MainDeployer");
       mbeanServer.registerMBean(mainDeployer, mainDeployerObjectName);
 
       // Add the deployment deployer
@@ -268,29 +275,59 @@
       // Deploy all files in deploy/
       if (deployDirectory != null && deployDirectory.exists() && deployDirectory.isDirectory())
       {
+         // Hot deployer
+         if (kernelConfiguration.isHotDeployment())
+         {
+            hotDeployer = new HotDeployer(kernelConfiguration.getHotDeploymentInterval(),
+                                          deployDirectory,
+                                          this);
+
+            ObjectName hotDeployerObjectName = new ObjectName(kernelConfiguration.getName() + ":name=HotDeployer");
+            mbeanServer.registerMBean(hotDeployer, hotDeployerObjectName);
+         }
+
          File[] files = deployDirectory.listFiles();
 
          if (files != null)
          {
+            List<URL> l = new ArrayList<URL>(files.length);
             int counter = 0;
+
             for (File f : files)
             {
-               if (f.toURI().toURL().toString().endsWith(".xml"))
+               URL u = f.toURI().toURL();
+               
+               l.add(u);
+
+               if (u.toString().endsWith(".xml"))
                   counter++;
+
+               if (hotDeployer != null)
+                  hotDeployer.register(u);
             }
 
             beanDeployments = new AtomicInteger(counter);
 
-            for (File f : files)
+            if (kernelConfiguration.isParallelDeploy())
             {
-               deployUrls(new URL[] {f.toURI().toURL()});
-            }                     
+               deployUrls(l.toArray(new URL[l.size()]));
+            }
+            else
+            {
+               for (URL u : l)
+               {
+                  deployUrls(new URL[] {u});
+               }
+            }
 
             if (counter > 0)
                incallback();
          }
       }
 
+      if (hotDeployer != null)
+         hotDeployer.start();
+
       // Remote MBeanServer access
       if (kernelConfiguration.isRemoteAccess())
       {
@@ -362,6 +399,12 @@
    {
       SecurityActions.setThreadContextClassLoader(kernelClassLoader);
 
+      // Stop hot deployer
+      if (hotDeployer != null)
+      {
+         hotDeployer.stop();
+      }
+
       // Stop the remote connector
       if (remote != null)
       {
@@ -379,6 +422,9 @@
 
          for (Deployment deployment : shutdownDeployments)
          {
+            if (hotDeployer != null)
+               hotDeployer.unregister(deployment.getURL());
+
             shutdownDeployment(deployment);
          }
       }
@@ -403,11 +449,14 @@
       if (temporaryEnvironment)
       {
          File tmp = new File(SecurityActions.getSystemProperty("java.io.tmpdir"));
-         File root = new File(tmp, "jboss-jca");
+         File root = new File(tmp, kernelConfiguration.getName());
 
          recursiveDelete(root);
       }
 
+      // Log shutdown
+      info(VERSION + " stopped");
+
       // Shutdown kernel class loader
       if (kernelClassLoader != null)
       {
@@ -421,9 +470,6 @@
          }
       }
 
-      // Log shutdown
-      info(VERSION + " stopped");
-
       // Reset to the old class loader
       SecurityActions.setThreadContextClassLoader(oldClassLoader);
    }
@@ -685,6 +731,15 @@
    }
 
    /**
+    * Get the hot deployer
+    * @return The hot deployer
+    */
+   public HotDeployer getHotDeployer()
+   {
+      return hotDeployer;
+   }
+
+   /**
     * Register an incallback method with the kernel
     * @param cb The callback structure
     */

Modified: projects/jboss-jca/trunk/fungal/src/main/java/org/jboss/jca/fungal/impl/remote/Communication.java
===================================================================
--- projects/jboss-jca/trunk/fungal/src/main/java/org/jboss/jca/fungal/impl/remote/Communication.java	2010-02-27 22:27:22 UTC (rev 101609)
+++ projects/jboss-jca/trunk/fungal/src/main/java/org/jboss/jca/fungal/impl/remote/Communication.java	2010-02-28 01:38:28 UTC (rev 101610)
@@ -23,6 +23,7 @@
 package org.jboss.jca.fungal.impl.remote;
 
 import org.jboss.jca.fungal.api.MainDeployer;
+import org.jboss.jca.fungal.impl.HotDeployer;
 
 import java.io.IOException;
 import java.io.ObjectInputStream;
@@ -45,6 +46,9 @@
    /** The main deployer */
    private MainDeployer mainDeployer;
 
+   /** The hot deployer */
+   private HotDeployer hotDeployer;
+
    /** Logging */
    private static Object logging;
 
@@ -52,11 +56,13 @@
     * Constructor
     * @param socket The socket
     * @param mainDeployer The main deployer
+    * @param hotDeployer The hot deployer
     */
-   public Communication(Socket socket, MainDeployer mainDeployer)
+   public Communication(Socket socket, MainDeployer mainDeployer, HotDeployer hotDeployer)
    {
       this.socket = socket;
       this.mainDeployer = mainDeployer;
+      this.hotDeployer = hotDeployer;
 
       if (logging == null)
          initLogging(SecurityActions.getThreadContextClassLoader());
@@ -76,11 +82,19 @@
          if (command == 0)
          {
             URL url = new URL(ois.readUTF());
+
+            if (hotDeployer != null)
+               hotDeployer.register(url);
+
             mainDeployer.deploy(url);
          }
          else if (command == 1)
          {
             URL url = new URL(ois.readUTF());
+
+            if (hotDeployer != null)
+               hotDeployer.unregister(url);
+
             mainDeployer.undeploy(url);
          }
          else

Modified: projects/jboss-jca/trunk/fungal/src/main/java/org/jboss/jca/fungal/impl/remote/CommunicationServer.java
===================================================================
--- projects/jboss-jca/trunk/fungal/src/main/java/org/jboss/jca/fungal/impl/remote/CommunicationServer.java	2010-02-27 22:27:22 UTC (rev 101609)
+++ projects/jboss-jca/trunk/fungal/src/main/java/org/jboss/jca/fungal/impl/remote/CommunicationServer.java	2010-02-28 01:38:28 UTC (rev 101610)
@@ -84,7 +84,7 @@
          {
             Socket socket = ss.accept();
 
-            Runnable r = new Communication(socket, kernel.getMainDeployer());
+            Runnable r = new Communication(socket, kernel.getMainDeployer(), kernel.getHotDeployer());
             Future<?> result = kernel.getExecutorService().submit(r);
          }
          catch (IOException ioe)

Modified: projects/jboss-jca/trunk/sjc/src/main/java/org/jboss/jca/sjc/Main.java
===================================================================
--- projects/jboss-jca/trunk/sjc/src/main/java/org/jboss/jca/sjc/Main.java	2010-02-27 22:27:22 UTC (rev 101609)
+++ projects/jboss-jca/trunk/sjc/src/main/java/org/jboss/jca/sjc/Main.java	2010-02-28 01:38:28 UTC (rev 101610)
@@ -61,6 +61,8 @@
       try
       {
          KernelConfiguration kernelConfiguration = new KernelConfiguration();
+         kernelConfiguration = kernelConfiguration.name("jboss.jca");
+         kernelConfiguration = kernelConfiguration.parallelDeploy(false);
 
          String home = SecurityActions.getSystemProperty("jboss.jca.home");
          if (home != null)




More information about the jboss-cvs-commits mailing list