6 Replies Latest reply on Dec 2, 2005 7:13 AM by Holger Casties

    Multiple Databases - Hot deployment of *-ds.xml and *.par

    Holger Casties Newbie

      Hi.

      I'am currently developing a (test) application which must support multiple databases.
      This application will be used by several users and must be able to create databases dynamically.
      The users do not have any access rights to the database management system.
      The databases will be accessed via dedicated EJB3-based services.

      The file structure of the deployment looks as follow:
      $JBOSS_HOME/server/default/deploy/DataBaseManagement/Postgres/postgres-ds.xml (DB management)

      $JBOSS_HOME/server/default/deploy/Projects/appX/appX.ejb3 (bean and entity classes)
      $JBOSS_HOME/server/default/deploy/Projects/appX/appX.war (Web interface classes)
      $JBOSS_HOME/server/default/deploy/Projects/appX/user1.par (contains user1 specific persistence.xml)
      $JBOSS_HOME/server/default/deploy/Projects/appX/user2.par (contains user2 specific persistence.xml)
      $JBOSS_HOME/server/default/deploy/Projects/appX/...


      My current incomplete solution (the workflow):
      1. A new database is created via separate DataBaseManagement bean (@Stateless) using ordinary JDBC:
      - creating a connection to the DBMS via getConnection()
      - creating a new database via SQL query
      - closing the connection

      2. The postgres-ds.xml obtains a user-db-specific <local-tx-datasource>.

      3. THE BAD THING: The application has to wait for a few seconds until JBOSS recognizes the changes in postgres-ds.xml.

      4. The application creates a user-specific par file (e.g. user1.par) and copies this one into the appX directory.

      5. THE BAD THING AGAIN: The application has to wait for a few seconds until JBOSS recognizes this new par file.

      6. The application (appX) can be used by the corresponding user.


      Here are my questions:
      a. How can I avoid 3. and 5.?

      b. Is is possible to enforce JBOSS to recognize the changes of *-ds.xml and *.par immediately (s.th. like flushing)?

      c. How can the application be triggered that JBOSS has recognized these changes?

      d. Relating to the par file: Is it possible to obtain the location (fully-qualified path) of appX.ejb3 from inside the appX-bean?


      Holger

        • 1. Re: Multiple Databases - Hot deployment of *-ds.xml and *.pa
          Bill Burke Master

          You can tell the MainDeployer through an MBean invocation to deploy any archive you want immediately. This is how our junit tests work in JBoss.

          • 2. Re: Multiple Databases - Hot deployment of *-ds.xml and *.pa
            Holger Casties Newbie

            Hi Bill.

            Thanx a lot for your prompt response.

            My problem is that I don't know how to achieve that.
            How can I get an appropriate MainDeployer?
            And how can I invoke this one through Mbean invocation?
            How have I to submit my par file to be deployed?

            A useful code sequence would help very much.


            Holger

            • 3. Re: Multiple Databases - Hot deployment of *-ds.xml and *.pa
              Holger Casties Newbie

              Hi.

              After looking through several forums I found some answers relating to my questions:
              An MBeanServer may be got in the following way:

              MBeanServerConnection mBeanServerConn = (MBeanServerConnection)ctx.lookup("jmx/invoker/RMIAdaptor");

              A MainDeployer could be retrieved via:
              ObjectName mainDeployer = new ObjectName(MainDeployer.OBJECT_NAME.getCanonicalName());


              Now I can use the MBeanServer.invoke method to invoke some MainDeployer methods like "listDeployers()".
              But I am not able to invoke the "deploy()" method in this way!

              What do I have to do?
              How can I deploy my par file?

              Holger

              • 4. Re: Multiple Databases - Hot deployment of *-ds.xml and *.pa
                Holger Casties Newbie

                Hi.

                I code the following to achieve hot deployment of 'postgres-ds.xml':

                // Get MBean server connection
                MBeanServerConnection mBeanServerConn = (MBeanServerConnection)ctx.lookup("jmx/invoker/RMIAdaptor");
                // Get MainDeployer
                ObjectName mainDeployer = MainDeployer.OBJECT_NAME;
                // Set params for method invocation:
                Object[] args = { dsFile }; // fully-qualified path to *-ds.xml file
                String[] sig = { "java.lang.String" };
                // Invoke the 'deploy' method
                mBeanServerConn.invoke(mainDeployer, "deploy", args, sig);


                But the xml file above WILL NOT be hot-deployed!

                What is missing in my code sequence?
                Or is there anything else to do, to achieve hot deployment?


                Holger


                • 5. Re: Multiple Databases - Hot deployment of *-ds.xml and *.pa
                  Holger Casties Newbie

                  Relating to my last post:

                  The *-ds.xml file will be hot-deployed but not immediately as wanted!
                  The changes will be detected after the 'ScanPeriod' time!
                  But that's too late!

                  • 6. Re: Multiple Databases - Hot deployment of *-ds.xml and *.pa
                    Holger Casties Newbie

                    Hi.

                    I think I found an acceptable solution to my problem.

                    Here is the running code:

                    /**
                     * This method enforces an immediate hot deployment of the submitted file.
                     * At first, the file will be deployed by the MainDeployer through
                     * MBeanServerConnection invocation.
                     * The second step is to invoke the DeploymentScanner's scan() method to achieve
                     * an immediate detection of the changes.
                     *
                     * @param deployFile
                     * Name of the file to be deployed (fully-qualified path name)
                     *
                     * @throws IOException
                     * @throws ReflectionException
                     * @throws MBeanException
                     * @throws InstanceNotFoundException
                     * @throws NullPointerException
                     * @throws MalformedObjectNameException
                     */
                    private void hotDeploy(String deployFile)
                     throws InstanceNotFoundException, MBeanException, ReflectionException,
                     IOException, MalformedObjectNameException, NullPointerException {
                     // Initialize the necessary services once:
                     if (mBeanServerConn == null) {
                     // Get MBeanServerConnection
                     mBeanServerConn = (MBeanServerConnection) sessionContext.lookup("jmx/invoker/RMIAdaptor");
                    
                     // Get MainDeployer
                     mainDeployer = MainDeployer.OBJECT_NAME;
                    
                     // Get DeploymentScanner
                     deploymentScanner = new ObjectName("jboss.deployment:type=DeploymentScanner,flavor=URL");
                     }
                    
                     { // Deploy submitted file:
                     // Set params for method invocation:
                     Object[] params = { deployFile };
                     String[] signatures = { "java.lang.String" };
                    
                     // Invoke the deploy() method of 'mainDeployer'
                     mBeanServerConn.invoke(mainDeployer, "deploy", params, signatures);
                     }
                    
                     { // Enforce immediate scanning of deployment:
                     // Set params for method invocation:
                     Object[] params = {};
                     String[] signatures = {};
                    
                     // Invoke the scan() method of 'deploymentScanner'
                     mBeanServerConn.invoke(deploymentScanner, "scan", params, signatures);
                     }
                    }



                    Holger