11 Replies Latest reply on Feb 13, 2013 1:23 PM by brian.stansberry

    How to override the module name of deployments?

    conorroche

      We are migrating from jboss 4.3.2 to jboss 7 - we are using jboss 7.1.3.Final which is built from that tag in the jboss git repo, up until now we have named our ears and wars with a version in the name e.g.

       

      componentA-1.1.0.ear

        -- componentA-ejb-1.1.0.jar

       

      the primary reason to name ears and wars with the version name in them is to allow someone see the versions of components by just doing an ls on the deploy dir as opposed to inspecting the manifest (script using jar/unzip -p etc commands can achieve the same but is slower).

       

      I have a different component say applicationB-2.0.war which depends on the componentA-ejb-1.1.0.jar, I can put this in the MANIFEST.MF of the war:

       

      <dependencies>deployment.componentA-1.1.0.ear.componentA-ejb-1.1.0.jar</dependencies>

       

      This works but is not good as it means if somone updates the version of componentA-1.1.0.ear then they would also have to put up a new version of applicationB-2.0.war

       

      I know i can either

       

      a) split out the ejb jar interfaces and related classes into a separate module and then the ejb jar and war can depend on that - this is a fair bit of project restructuring which i would prefer not to do

      b) rename the ear and ejb jar NOT to have a version in the file names - which i will go with unless module-alias works..

       

      I had hoped to be able to use the ears jboss-deployment-structure.xml to alias the deployment and sub deployment:

       

      <?xml version="1.0" encoding="UTF-8"?>

      <jboss-deployment-structure xmlns="urn:jboss:deployment-structure:1.1">

          <ear-subdeployments-isolated>false</ear-subdeployments-isolated>

          <deployment>

              <module-alias name="componentA"/>

          </deployment>

          <sub-deployment name="componentA-ejb-${project.version}.jar">

              <module-alias name="componentA-ejb.jar"/>

          </sub-deployment>

      </jboss-deployment-structure>

       

      and then refer to the ejb module from the war as:

       

      <dependencies>deployment.componentA.componentA-ejb.jar</dependencies>

       

      But this does not work, i have also tried referring directly to the sub module alias e.g. <dependencies>deployment.componentA-ejb.jar</dependencies> and that doesnt work either.

       

      Can anyone tell me if the deployment/sub-deployment module-alias should affect the modules loaded by the Service Module Loader? I only see module loaded info logs referring to the filename of the ear and ejb jar...

       

      Perhaps this is something that is only implemented in 7.2.0-alpha?

        • 1. Re: How to override the module name of deployments?
          nickarls

          How do you build your application? Maven? Is this a build issue or do you use an exploded EAR and want to drop in new stuff "live"?

          • 2. Re: How to override the module name of deployments?
            conorroche

            Yes i build the application with maven but its not a build issue e.g. when i talk about dependencies i mean jboss module dependencies not maven dependencies. I want to be able to refer to an ejb jar deployment module as a jboss modules dependency by a name that starts with something other than the ear filename e.g. be able to specify the module name in a jee descriptor/jboss config file.

             

            So for example in deployments folder i would have a non exploded ear:

             

            myapp-3.2.3.ear

             

            which has this structure:

             

                 - META-INF/application.xml (this has the jee application-name set as myapp)

                 - META-INF/jboss-deployment-structure.xml (this has the top level deployment module-alias set as myapp)

                 - myapp-ejb.jar

                      - ejb-jar.xml (this has the jee module-name set as myapp-ejb)

             

            and in a standalone war file i want to add the ejb jar module to the war classpath as a jboss module so my war has this struture:

             

            myapp.war

                 - META-INF/MANIFEST.MF (this has a jboss modules dependencies entry to include the myapp.ejb.jar on the class path Dependencies: deployment.myapp-3.2.3.ear.myapp-ejb.jar)

                 - WEB-INF/classes

             

            The issue is that i can not refer to the ejb jar as a jboss modules dependency using anything other than the ear filename, i would like to be able to refer to it as

             

            Dependencies: deployment.myapp.ear.myapp-ejb.jar

             

            So module-alias in the jboss-deployment-structure.xml doesnt appear to do anything.

            The application name and jee module name do allow me to control the jndi bindings so it would seem more consistent if either those or the jboss-deployment-structure.xml allowed me to control the name of a deployment module when loaded into the jboss modules system.

            • 3. Re: How to override the module name of deployments?
              nickarls

              and the Dependencies: is nothing you can use an ${} expression during build to populate?

              • 4. Re: How to override the module name of deployments?
                conorroche

                yes i can populate it as part of packaging but if i did i would end up with this in the deployments folder:

                 

                myapp.war - with Dependencies entry in the manifest referring to ear  name myapp-3.2.3.ear e.g. Dependencies: deployment.myapp-3.2.3.ear.myapp-ejb.jar

                myapp-3.2.3.ear

                 

                the issue with this is that when a new version of myapp ear is deployed e.g. myapp-4.0.ear is deployed and replaces myapp-3.2.3.ear then myapp.war would have to have its manifest file updated, now given that the ear in question is actually used by many wars this isnt feasible e.g. if you make non interface changes to a component you shouldnt have to deploy/modify all the wars that depend on it.

                 

                so i am left wih not using a version in the ear file name in order to have a consistent name for the jboss deployment module so i dont have to change any dependents when i update the version of the ear unless there is a way for me to customise the jboss module name to be something other than the file name.

                • 5. Re: How to override the module name of deployments?
                  jjfraney

                  I too have this requirement.  Let me describe with a use case.

                   

                  First, remember, we want an easy way to view (and confirm) the  versions of deployed ear and war.  Retaining the version in the deployable name is the easiest way.  If there is another easy way, please suggest.

                   

                  Also, this is not resolved at build time (e.g., with maven's resource filter).  The dependency name is changing (version number), not the dependent.  We are expressly avoiding a rebuild of the dependent and so do not have the opportunity to update the dependent's reference to the dependency.

                   

                  Above, conor describes a war depending on an ear.  Let us say we want to upgrade the ear without upgrading the war.  This is reasonable because some change is local to the ear.  In other words, the war does not have to change.  In this case, the war will remain at its current release, and the ear will be bumped up a release.  The old ear removed and the new ear replaces it.  Another reasonable use case would be multiple war deployments depending on the same ear, and all components have their own release cycle.

                   

                  Conor and I are stumped by how to refer to the dependency (the ear) in such a way as to be isolated from the dependency's file name change (due to version number).

                   

                  So, back in November, it looks like conor is giving up the ability to easily confirm the versions of deployed ear war.  I'm still holding out for an answer to this question.  I don't see a definitive end to this post.

                   

                   

                  Jboss modules has a way of dealing with this issue.  The module's 'slot' is not a direct mapping to the version number of the module's content.  For example, a slot name ':2.3' could have jars with version 2.3.1 or 2.3.2 at different times. So, in this way, an update to the content of the slot will be effective.  And the version of a component can be confirmed by looking at the content of the module's slot directory.  However, I have one question on this approach: Does jboss container scan these for j2ee components (for example, loads an ear as a j2ee application)?

                   

                  OSGI has a solution, too, allowing for version ranges to be specified by dependents.  However, I do not see this concept expressed in the class loading document of jboss as7.  I don't expect to use jboss OSGI to resolve this issue, but will listen.  I raise OSGI as an alternate way of expressing the requirement.

                   

                  Thanks.

                  • 6. Re: How to override the module name of deployments?
                    conorroche

                    John,

                     

                    In the end i went with the workaround of having all the ears without a version in their name e.g. notification-engine.ear but with a Manifest entry for the version, i then added a script to the deployments dir to display the versions which can be used by someone looking in the deployments dir, here is the script in case ur interested:

                     

                    #!/bin/bash

                     

                    # This loops through rar, ear and war files and for each one displays its version from the manifest file

                    file_types=( "rar" "ear" "war" )

                     

                    shopt -s nullglob

                    for file_type in "${file_types[@]}"

                    do

                        echo "$file_type files:"

                        for f in *.${file_type}

                        do

                               version=`unzip -p $f META-INF/MANIFEST.MF | grep Version | grep -v Archiver | grep -v Manifest | grep -v Specification | grep -v Ant | head -n 1`

                               echo "$f : $version"

                        done

                    done

                     

                    Separately I came across a lot of issues with the class load order on startup where i have ears depending on other ears etc, having spent a load of time on it i ended up using a script on startup that clears the deployments dir and copies ears/wars in order from a holding dir into it so they deploy in an order that works. Here is an example of the script that copies in the files in case its of use to you:

                     

                    #!/bin/bash

                     

                    if [ -z "$DEPLOY_WAIT" ]; then

                      DEPLOY_WAIT=60

                    fi

                     

                    if [ -z "$PREP_DIR" ]; then

                      PREP_DIR=/Applications/jboss-as-7.1.3.Final/standalone/deployments.prep

                    fi

                     

                    if [ -z "$DEPLOY_DIR" ]; then

                      DEPLOY_DIR=/Applications/jboss-as-7.1.3.Final/standalone/deployments

                    fi

                     

                    if [ -z "$JBOSS_CONSOLE_LOG" ]; then

                      JBOSS_CONSOLE_LOG=/Applications/jboss-as-7.1.3.Final/standalone/log/standalone-console.log

                    fi

                     

                     

                    # this function deploys one or more files in parallel

                    function deploy_files (){

                      FILE_NAMES=$1

                      echo ""

                      # copy all the given files at once so they can deploy in parallel

                      any_failed=false

                      arr=$(echo $FILE_NAMES | tr "," "\n")

                      declare -a deploy_results

                      i=0

                      for FILE_NAME in $arr

                      do

                        if [ ! -f $PREP_DIR/$FILE_NAME ]; then

                          echo "The deploy source file was not found: $PREP_DIR/$FILE_NAME"

                          deploy_results[$i]='nonexistent'

                          any_failed=true

                          else

                            echo "Deploying $FILE_NAME ..."   

                          cp $PREP_DIR/$FILE_NAME $DEPLOY_DIR/

                          deploy_results[$i]='waiting'

                          fi

                          ((i++))

                      done

                     

                      # wait for the files to be deployed

                      echo "waiting for: $FILE_NAMES to be deployed."

                     

                      # loop for up to deploy wait, checking if each file is deployed

                      count=0

                      alldeployed=false

                      until [ $count -gt $DEPLOY_WAIT ]

                      do

                       

                        any_remaining=false

                        i=0

                        for FILE_NAME in $arr

                        do

                          if [ ${deploy_results[$i]} = 'waiting' ]; then

                              any_remaining=true

                              grep "Deployed \"$FILE_NAME\"" $JBOSS_CONSOLE_LOG > /dev/null

                            if [ $? -eq 0 ] ; then

                              deploy_results[$i]='deployed'

                              #echo ""

                              echo "Deployed file: $FILE_NAME"

                            else

                              # check for deployment failure...

                              grep 'Stopped deployment $FILE_NAME' $JBOSS_CONSOLE_LOG > /dev/null

                              if [ $? -eq 0 ] ; then

                                deploy_results[$i]='failed'

                                #echo ""

                                echo "Failed to deploy file: $FILE_NAME"

                              fi

                            fi        

                          fi 

                          ((i++))    

                        done

                        if [ $any_remaining = false ]; then

                            if [ $any_failed = true ]; then

                                return 1

                            else

                                return 0

                            fi

                        fi

                        echo -n "."

                        sleep 1

                        ((count++))

                      done

                      echo "Error: All deployments did not complete within the timeout of $DEPLOY_WAIT secs"

                      return 2

                    }

                     

                    date1=$(date +"%s")

                    echo "Deploying components from the prep dir: $PREP_DIR in sequence..."

                     

                    deploy_files xmpp-jca-ra.rar,platform-version-displayer.war,template-engine.ear,notification-engine-server.ear

                    deploy_files enso-engine.ear,core.ear,platform-api-security.ear

                    deploy_files user-api.ear,rtr-url-shortener-api.ear

                    deploy_files tracking-api.ear,microblog-api.ear,pricing-api.ear,watch-api.ear

                    deploy_files common-app.ear

                    deploy_files file-transfer-manager.ear,device-api.ear,group-api.ear,vehicle-api.ear,search-api.ear,importexport-api.ear,pathdata-api.ear,plugin-api.ear

                    deploy_files rtr-user-api.ear

                    deploy_files rtr-notification-api.ear,rtr-report-api.ear,payment-module.ear

                    deploy_files demand-api.ear

                    deploy_files trip-api-v2.ear

                    deploy_files trip-api.ear

                    deploy_files platform-api.ear,single-sign-on.war,sms-inbound.war,rtr-desktop-web.war,rtr-mobile-web.war,rtr-web-ui.war,rtr-monitor.ear,rtr-departure-board.war,rtr-tv-board.war

                     

                    date2=$(date +"%s")

                    diff=$(($date2-$date1))

                    echo "Finished deploying components in $diff seconds."

                     

                     

                     

                     

                     

                     

                    Conor

                    • 7. Re: How to override the module name of deployments?
                      brian.stansberry

                      A deployment has two names:

                       

                      • "name", which is a management notion, i.e. controls the name of the root resource for the deployment in the management resource tree.
                      • "runtime-name", which is the name by which the deployment is known to the various deployment processors that actually deploy it.

                       

                      Typically these have the same value. By default, if the user doesn't provide a runtime-name, the AS uses the "name"  as the runtime-name as well.

                       

                      The reason we have two names is to support cases where people want multiple versions of something under management. You can have 10 different deployments with runtime-name foo.war available on your system, so long as they all have different values for "name". So, deployments with "name" values of "foo_v1", "foo_v2" etc, all with runtime-name "foo.war". Only one of these can be deployed on a given server; the rest can't be enabled. But they can all be there, with the bits on the server and an entry for them in standalone.xml or domain.xml.

                       

                      These names can be controlled via the CLI deploy command, which includes two params:

                       

                      --name            - the unique name of the deployment. If the file path

                                           argument is specified the name argument is optional with

                                           the file name been the default value. If the file path

                                           argument isn't specified then the command is supposed to

                                           enable an already existing but disabled deployment, and in

                                           this case the name argument is required.

                       

                       

                      --runtime-name    - optional, the runtime name for the deployment.

                       

                      The xsd for the standalone.xml/domain.xml <deployment> element also provides separate attributes for name and runtime-name.

                      • 8. Re: How to override the module name of deployments?
                        brian.stansberry

                        A detail I missed: the module names for deployments should be based on the runtime-name. (If they're not it's a bug.)

                        • 9. Re: How to override the module name of deployments?
                          jjfraney

                          That then is the final answer to this dilemma:

                           

                          Using cli or domain.xml, specify a runtime-name that does not have a version specifier.  'name' defaults to the deployment's filename which contains the version specifier.  Dependents refer to the dependency using the runtime name.

                           

                          So, the above example,

                           

                          myapp-2.3.2.ear deploys as: runtime-name: myapp.ear, name: myapp-2.3.2.ear

                          myapp.war specifies Dependencies as 'myapp.ear.myejb.jar

                           

                          To upgrade myapp

                          myapp-2.3.3 deploys as: runtime-name: myapp.ear, name: myapp-2.3.3.ear

                          disable deployable: name: myapp-2.3.2

                          enable deployable: name: myapp-2.3.3

                           

                          Thanks.

                          • 10. Re: How to override the module name of deployments?
                            conorroche

                            I was looking for an approach for when deployments are done automatically by being in the deployments dir and not via the CLI, I think it would be nice if the runtime name of the deployment could be specified in the deployment descriptor

                            • 11. Re: How to override the module name of deployments?
                              brian.stansberry

                              conor roche wrote:

                               

                              I was looking for an approach for when deployments are done automatically by being in the deployments dir and not via the CLI, I think it would be nice if the runtime name of the deployment could be specified in the deployment descriptor

                               

                              I haven't looked into this in any detail at all, and unfortunately don't have time to , but the standard EE deployment descriptors have elements for setting application/module name. It might be possible to use that data to drive the name of the module. You could raise a feature request JIRA for this.