6 Replies Latest reply on Oct 13, 2006 2:20 PM by starksm64

    Need more metadata for the JARStructure deployer

    starksm64

      Right now the JARStructure deployer is stumbling around in the dark trying to identify whatever gets passed to it. The two problems I am current seeing are:

      1. Its traversing directories it should not, for example, a directory entry in a jar archive.
      2. Its not traversing directories it should, for example, a child directory in top level deployment (jbossweb-tomcat6.deployer/jsf-libs).

      This might be conflicts in the deployment oriented VFS.isArchive attribute, isLeaf, or just bugs, but we need the ability to explicitly define what the structure of a deployment is in terms of deployment contexts and classpath entries via metadata. With such a notion the ear structure deployer would just be a deployer that obtained this metadata via alternate descriptors. The JARStructure deployer would just be java coded logic to produce this metadata. So basically and extension of the ear application.xml structural elements (module and lib dirs) is what I'm thinking of.

        • 1. Re: Need more metadata for the JARStructure deployer
          starksm64

          Another aspect that should be applied to the recognized classpath indepdendent of the structure deployer is the VFSUtils.addManifestLocations behavior. The base classpath should be augmented via classpath manifest after the structure is determined.

          What if the StructureDeployer is updated to support an explicit StructureMetaData notion:

          public interface StructureDeployer
          {
           /**
           * Determine the structure of a deployment
           *
           * @param context the context
           * @return true when it is recongnised
           */
           boolean determineStructure(DeploymentContext context, StructureMetaData);
          ...
          
          public interface StructureMetaData
          {
           /** The paths of subdeployments relative to the root DeploymentContext */
           public String[] getDeploymentPaths();
           /** The paths of classpath entries relative to the root DeploymentContext */
           public String[] getClasspathFiles();
          }
          


          and instead of the first structure deployer determining the structure, all deployers can interact to augment the StructureMetaData. Creating DeploymentContexts and filling out the classpath based on manifests, etc would be aspects of the MainDeployer rather than structural deployer behaviors.


          • 2. Re: Need more metadata for the JARStructure deployer
            starksm64

            I just checked in an update to the deployer that adds a DeclaredStructure deployer which is driven off a META-INF/jboss-structure.xml descriptor. From the org.jboss.test.deployers.structure.explicit.test.DeclaredStructureUnitTestCase, there is a complex.deployer deployment similar to the tomcat war deployer:

            complex.deployer/
            complex.deployer/cp-mf.jar/
            complex.deployer/cp-mf.jar/info
            complex.deployer/x.war/
            complex.deployer/x.war/WEB-INF/
            complex.deployer/x.war/WEB-INF/classes/
            complex.deployer/x.war/WEB-INF/lib/
            complex.deployer/x.war/WEB-INF/lib/w0.jar/
            complex.deployer/sub.jar/
            complex.deployer/sub.jar/empty
            complex.deployer/sub.jar/META-INF/
            complex.deployer/sub.jar/META-INF/MANIFEST.MF
            complex.deployer/lib-dir/
            complex.deployer/lib-dir/jar2.jar/
            complex.deployer/lib-dir/jar2.jar/META-INF/
            complex.deployer/lib-dir/jar2.jar/META-INF/MANIFEST.MF
            complex.deployer/lib-dir/jar0.jar/
            complex.deployer/jar1.jar/
            complex.deployer/META-INF/
            complex.deployer/META-INF/jboss-structure.xml
            


            whose complex.deployer/META-INF/jboss-structure.xml is:
            <structure>
             <context>
             <path name="complex.deployer" />
             <metaDataPath name="META-INF" />
             <classpath>
             <path name="jar1.jar" />
             <path name="lib-dir" suffixes=".jar" />
             </classpath>
             </context>
             <context>
             <path name="complex.deployer/sub.jar" />
             <metaDataPath name="META-INF" />
             </context>
             <context>
             <path name="complex.deployer/x.war" />
             <metaDataPath name="WEB-INF" />
             <classpath>
             <path name="WEB-INF/classes" />
             <path name="WEB-INF/lib" suffixes=".jar" />
             </classpath>
             </context>
            </structure>
            


            Any declared context with a META-INF/MANIFEST.MF declaring a Class-Path is also used to augment the context classpath, as is the Class-Path of any entry added via the descriptor classpath.

            I'll intgrate this into the jboss5 trunk tomorrow when I check in the tomcat.deployer work.


            • 3. Re: Need more metadata for the JARStructure deployer

               

              "scott.stark@jboss.org" wrote:
              Right now the JARStructure deployer is stumbling around in the dark trying to identify whatever gets passed to it. The two problems I am current seeing are:

              1. Its traversing directories it should not, for example, a directory entry in a jar archive.


              That sounds like a bug, if they are are not just candidates
              getting rejected later on.


              2. Its not traversing directories it should, for example, a child directory in top level deployment (jbossweb-tomcat6.deployer/jsf-libs).


              Why should it?

              • 4. Re: Need more metadata for the JARStructure deployer

                 

                "scott.stark@jboss.org" wrote:
                I just checked in an update to the deployer that adds a DeclaredStructure deployer which is driven off a META-INF/jboss-structure.xml descriptor.


                It was an abstract deployer structure notion like this
                that I was going to use to write the EARDeployer,
                but Bill got there first, I haven't looked at what he has done.

                This is also something I wanted to work out to give what I called
                the "structure view" rather than exposing the whole deployment
                context.

                I don't like using String[] for this kind of stuff.

                1) The array is immutable (you can't change its length)
                2) You can't create the metadata "lazily"
                (without copying an entire list to an array when it requested)
                3) String is inextensible so it becomes impossible to annotate
                (add attributes) to this piece of metadata.

                I haven't looked at what you checked in.
                But this also needs to work in the case where this metadata
                is passed in at deployment time rather than read from the xml.

                We also need to rewrite the way the StructureDeployers are invoked
                (partly to give the scanner a chance to determine whether
                a file is a deployment so we can replace the archive notion in the VFS).

                Currently, it builds up a list of candidates for each deployment
                then this *potentially big* list is check to see whether they are
                actually real.
                So there really needs to be a factored out StrutureDeployers
                object that can be reused outside the MainDeployer
                1) By the scanner
                2) By each structure deployer to resurse into to avoid creating the big list

                • 5. Re: Need more metadata for the JARStructure deployer
                  starksm64

                   

                  "adrian@jboss.org" wrote:


                  2. Its not traversing directories it should, for example, a child directory in top level deployment (jbossweb-tomcat6.deployer/jsf-libs).


                  Why should it?


                  Because it does in jboss4. As we discussed, we need to remove the isArchive from the VFS, and come up with an explicit structural deployment phase that allows for both jboss and hibernate to analyze a deployment. The output of this should be a StructureMetaData model that can be used by the MainDeployer to produce DeploymentContexts. The DeploymentContext is currently too heavy an object to just be a representation of a deployment structure.


                  • 6. Re: Need more metadata for the JARStructure deployer
                    starksm64

                    The current StructureMetaData used by the DeclaredDeployer consists of:

                    public class StructureMetaData
                    {
                     private HashMap<String, ContextInfo> contexts = new HashMap<String, ContextInfo>();
                    
                     public void addContext(ContextInfo context)
                     {
                     contexts.put(context.getVfsPath(), context);
                     }
                     public ContextInfo getContext(String vfsPath)
                     {
                     return contexts.get(vfsPath);
                     }
                    }
                    
                    public class ContextInfo
                    {
                     static class Path
                     {
                     private String name;
                     private String[] suffixes = {};
                     Path(String name, String suffixes)
                     {
                     this.name = name;
                     if( suffixes != null )
                     this.suffixes = suffixes.split(",");
                     }
                     public String getName()
                     {
                     return name;
                     }
                     public String[] getSuffixes()
                     {
                     return suffixes;
                     }
                     }
                    
                     /** The relative VFS path */
                     private String vfsPath;
                     /** The optional context classpath */
                     private ArrayList<Path> classPath;
                     /** The optional context metadata path */
                     private String metaDataPath;
                    
                     public List<Path> getClassPath()
                     {
                     return classPath;
                     }
                     public void setClassPath(List<Path> classPath)
                     {
                     if( this.classPath == null )
                     this.classPath = new ArrayList<Path>();
                     this.classPath.clear();
                     this.classPath.addAll(classPath);
                     }
                     public String getMetaDataPath()
                     {
                     return metaDataPath;
                     }
                     public void setMetaDataPath(String metaDataPath)
                     {
                     this.metaDataPath = metaDataPath;
                     }
                     public String getVfsPath()
                     {
                     return vfsPath;
                     }
                     public void setVfsPath(String path)
                     {
                     this.vfsPath = path;
                     }
                    }
                    


                    So you have a map of deployment contexts (ContextInfo) with the key being the VFS relative path for the deployment context.