6 Replies Latest reply on Jan 29, 2009 6:02 AM by Ales Justin

    Using temp at undeploy

    Ales Justin Master

      WRT:
      - https://jira.jboss.org/jira/browse/JBSEAM-3702

      Moving Norman's post here:

      "Norman Richards" wrote:

      Do you have a complete example of a jboss-structure.xml that works? Whenever I tried to create one, the only effect was that the application would be completely ignored and wouldn't deploy. Is it realistic to create a jboss-structure.xml that will work across multiple example apps with roughly the same structure? What about WAR files? I guess we would need two versions for each app - one for deploying as an EAR and for deploying as a WAR, right?

      Is there any way we can add metadata to the jboss-app.xml to indicate how we want the app treated? It seems like this should be at most a one-line change for an app, if not the default behavior for the server. Deleting the file from the deploy directory has always been a clean way to undeploy an application, and it's really strange that now we don't have a clean undeploy. I'm not trying to be overly critical. I'm just trying to figure out what our official answer is to someone who asls "How do I undeploy an application?".

      Before you could use the MBeans to deploy/undeploy an application. Undeploying did not remove the files from the deploy directory. In fact, you could easily use the MBeans to deploy/undeploy an application directly from your own project's build directory if you wanted. We generally didn't do that because making a connection to the MBeanServer required a login, which complicates things. But, it was definitely an option.


      I'm thinking of some programmatic addition of this at structure recognition.
      e.g. adding temp modification type to ContextInfo instance
      I'll have a better look on Friday, but any suggestions/ideas welcome.


        • 1. Re: Using temp at undeploy
          Ales Justin Master

          I did some initial impl under this JIRA:
          - https://jira.jboss.org/jira/browse/JBDEPLOY-154

          • 2. Re: Using temp at undeploy
            Ales Justin Master

            Describing what I did.
            Discussing whether it's not too much of a hack.

            Currently the only way to apply ModificationType is via jboss-structure.xml/context/modification=temp|unpack|explode.
            Which sounds a bit too limiting for a simple modification=temp instruction.

            The way current structure recognition part of VDF works, we need to get that info before
            StructureBuilder::populateContext is invoked in AbstractStructuralDeployers::determineStructure.

            What I've done is introduced a new StructureDeployer,
            which actually doesn't recognize the structure, but knows how to
            recognize if there should be any modification.

            public class ModificationTypeStructureDeployer implements StructureDeployer
            {
             private List<ModificationTypeMatcher> matchers;
            
             public boolean determineStructure(StructureContext context) throws DeploymentException
             {
             if (matchers != null && matchers.isEmpty() == false)
             {
             for (ModificationTypeMatcher matcher : matchers)
             {
             if (matcher.determineModification(context))
             {
             break;
             }
             }
             }
             return false;
             }
            
             /**
             * Set modification type matchers.
             *
             * @param matchers the modification type matchers.
             */
             public void setMatchers(List<ModificationTypeMatcher> matchers)
             {
             this.matchers = matchers;
             }
            
             /**
             * Add modification type matcher.
             *
             * @param matcher the modification type matcher
             */
             public void addMatcher(ModificationTypeMatcher matcher)
             {
             if (matchers == null)
             matchers = new ArrayList<ModificationTypeMatcher>();
            
             matchers.add(matcher);
             }
            
             /**
             * Remove modification type matcher.
             *
             * @param matcher the modification type matcher
             */
             public void removeMatcher(ModificationTypeMatcher matcher)
             {
             if (matchers != null)
             {
             matchers.remove(matcher);
             }
             }
            
             public boolean isSupportsCandidateAnnotations()
             {
             return false;
             }
            
             public int getRelativeOrder()
             {
             return 1;
             }
            }
            

            It runs right after DeclarativeStructureDeployer.

            Actually the parts that recognize if modification should kick in are ModificationTypeMatcher implementations.
            They add this information to StructureContext, which then passes it fwd in AbstractStructureDeployer::applyContextInfo
            where the real ContextInfo is created or it's directly applied if one of the children sets modification to top level ContextInfo.

            Here is an example of such ModificationTypeMatcher.
            It matches any path in any deployment level.
            public class FileModificationTypeMatcher extends AbstractModificationTypeMatcher
            {
             private String[] paths;
            
             public FileModificationTypeMatcher(String... paths)
             {
             if (paths == null || paths.length == 0)
             throw new IllegalArgumentException("Null or empty paths");
            
             this.paths = paths;
             }
            
             /**
             * Get the starting file.
             *
             * @param structureContext the structure context
             * @return the startting file; where do we start checking for paths
             */
             protected VirtualFile getStartingFile(StructureContext structureContext)
             {
             return structureContext.getFile();
             }
            
             protected boolean isModificationDetermined(StructureContext structureContext)
             {
             VirtualFile startingFile = getStartingFile(structureContext);
             for (String path : paths)
             {
             try
             {
             if (startingFile.getChild(path) != null)
             return true;
             }
             catch (Exception e)
             {
             log.debug("Cannot determine modification type, cause: " + e);
             }
             }
             return false;
             }
            }
            

            e.g. we could look for META-INF/web-beans.xml (still using the old name)

            Wdyt, too much of a hack?

            • 3. Re: Using temp at undeploy
              Ales Justin Master

               

              "alesj" wrote:
              Wdyt, too much of a hack?

              Thinking about it over the weekend,
              it's actually not a hack, it's bad design - conceptually completely wrong. :-(

              OK, not all parts are bad. :-)
              I'll redesign the current stuff to work against AbstractStructureBuilder,
              preparing the ContextInfo before the actual DeploymentContext creation.

              More to follow ...


              • 4. Re: Using temp at undeploy
                Ales Justin Master

                 

                "alesj" wrote:

                More to follow ...

                OK, I'm done with the change,
                and I'm happy with how it's done. :-)

                I added a simple StructureProcessor interface
                public interface StructureProcessor
                {
                 /**
                 * Prepare structure metadata.
                 *
                 * @param deployment the deployment
                 * @param structureMetaData the structure metadata
                 */
                 void prepareStructureMetaData(Deployment deployment, StructureMetaData structureMetaData);
                
                 /**
                 * Prepare context info.
                 *
                 * @param parentDeploymentContext the parent deployment context
                 * @param contextInfo the context info
                 */
                 void prepareContextInfo(DeploymentContext parentDeploymentContext, ContextInfo contextInfo);
                
                 /**
                 * Apply structure metadata.
                 *
                 * @param deploymentContext the deployment context
                 * @param structureMetaData the structure metadata
                 */
                 void applyStructureMetaData(DeploymentContext deploymentContext, StructureMetaData structureMetaData);
                
                 /**
                 * Apply context info.
                 *
                 * @param deploymentContext the deployment context
                 * @param contextInfo the context info
                 */
                 void applyContextInfo(DeploymentContext deploymentContext, ContextInfo contextInfo);
                }
                

                which gets appropriately called in AbstractStructureBuilder.

                Currently the only impl is ModificationTypeStructureProcessor.
                This one hold a list of previously mentioned ModificationTypeMatchers.
                ModificationTypeMatcher now looks like this:
                public interface ModificationTypeMatcher
                {
                 /**
                 * Should we modify the file.
                 *
                 * @param root the deployment root
                 * @param structureMetaData the current structure metadata
                 * @return true if we determined modification
                 */
                 boolean determineModification(VirtualFile root, StructureMetaData structureMetaData);
                
                 /**
                 * Should we modify the file.
                 *
                 * @param root the deployment root
                 * @param contextInfo the current context info
                 * @return true if we determined modification
                 */
                 boolean determineModification(VirtualFile root, ContextInfo contextInfo);
                }
                


                The test on how this is applied in 'reality':
                - http://anonsvn.jboss.org/repos/jbossas/projects/jboss-deployers/trunk/deployers-vfs/src/test/java/org/jboss/test/deployers/vfs/structureprocessor/test/VFSStructureProcessorUnitTestCase.java


                • 5. Re: Using temp at undeploy
                  Scott Stark Master

                  I'm looking through the changes, and it appears this automatically identifies contexts as temps if a specified metadata file exists. In the server we would presumably register all know deployment descriptors?

                  Its possible to have a nested deployment that has no descriptors. In that case you still will have to include a jboss-structure.xml I take it?

                  • 6. Re: Using temp at undeploy
                    Ales Justin Master

                     

                    "scott.stark@jboss.org" wrote:
                    I'm looking through the changes, and it appears this automatically identifies contexts as temps if a specified metadata file exists. In the server we would presumably register all know deployment descriptors?

                    You register what you like. :-)
                    You can either change whole StructureProcessor impl,
                    or you can just add custom ModificationTypeMatcher(s).

                    My drive for this was Seam's request to have temp for all Seam apps,
                    hence I needed to recognize/match deployments that are possible Seam apps.

                    This is what we need to add in order to make it happen:
                     <bean name="ModificationTypeStructureProcessor" class="org.jboss.deployers.vfs.plugins.structure.modify.ModificationTypeStructureProcessor">
                     <incallback method="addMatcher"/>
                     <uncallback method="removeMatcher"/>
                     </bean>
                    
                     <!-- The holder for deployers that determine structure -->
                     <bean name="StructuralDeployers" class="org.jboss.deployers.vfs.plugins.structure.VFSStructuralDeployersImpl">
                     <property name="structureBuilder">
                     <!-- The consolidator of the structure information -->
                     <bean name="StructureBuilder" class="org.jboss.deployers.vfs.plugins.structure.VFSStructureBuilder">
                     <property name="structureProcessor"><inject bean="ModificationTypeStructureProcessor"/></property>
                     </bean>
                     </property>
                    
                    public class SeamModificationTypeMatcher extends TempTopModificationTypeMatcher
                    {
                     public SeamModificationTypeMatcher()
                     {
                     super(SeamConstants.SEAM_FILES);
                     }
                    }
                    
                     <!-- Seam modification type matcher -->
                     <bean name="SeamMTMatcher" class="org.jboss.seam.integration.microcontainer.deployers.SeamModificationTypeMatcher"/>
                    
                    


                    "scott.stark@jboss.org" wrote:

                    Its possible to have a nested deployment that has no descriptors. In that case you still will have to include a jboss-structure.xml I take it?

                    Yes.

                    Or you can write a different StructureProcessor or
                    a ModificationTypeMatcher that doesn't 'work' on descriptors;
                    e.g. might work on classpath or predetermined attachments