1 2 Previous Next 28 Replies Latest reply on Jan 7, 2005 6:53 PM by starksm64 Go to original post
      • 15. Re: NEW BUILD

        Before I go further, the two files can be combined if you just want a standalone
        project, e.g.: This file will actually cause my ant classes to build themselves...

        <?xml version="1.0"?>
        
        <!--
         JBoss, the OpenSource J2EE webOS
        
         Distributable under LGPL license.
         See terms of license at gnu.org.
        -->
        <project name="project"
         default="build"
         basedir="."
        >
         <!-- Import the types -->
         <import file="src/resources/tasks.xml"/>
        
         <build id="JBossBuild" targetdefs="targets" description="The main build">
        
         <component id="ant">
         <artifact id="ant.jar"
         location="file:///usr/java/apache-ant-1.6.2/lib/ant.jar"
         />
         </component>
        
         <component id="jbossbuild">
         <artifact id="jbossbuild.jar"/>
         <artifact id="jbossbuild.api"/>
         </component>
         </build>
        
         <!-- The component definition -->
         <componentdef component="jbossbuild" description="JBoss Build">
        
         <source id="main">
         <include input="ant.jar"/>
         </source>
        
         <artifactdef artifact="jbossbuild.jar">
         <include input="main"/>
         </artifactdef>
        
         <artifactdef artifact="jbossbuild.api">
         <include input="main"/>
         </artifactdef>
         </componentdef>
        
        </project>
        


        • 16. Re: NEW BUILD

          Finally we have the tasks.xml where all the magic occurs:

          <?xml version="1.0"?>
          
          <!--
           JBoss, the OpenSource J2EE webOS
          
           Distributable under LGPL license.
           See terms of license at gnu.org.
          -->
          <project name="jboss.ant.tasks"
           default="help"
          >
           <!-- PROPERTIES -->
          
           <!-- JBoss Tasks Classpath -->
           <property name="jboss.tasks.path"
           value="../jbossbuild/output/eclipse-classes/main"
           />
          
           <!-- TYPEDEFS -->
          
           <!-- The build type -->
           <typedef name="build"
           classname="org.jboss.ant.types.build.Build"
           loaderRef="jboss.tasks.path"
           classpath="${jboss.tasks.path}"
           />
          
           <!-- The artifact type definition type -->
           <typedef name="artifacttype"
           classname="org.jboss.ant.types.build.ArtifactType"
           loaderRef="jboss.tasks.path"
           classpath="${jboss.tasks.path}"
           />
          
           <!-- The component definition type -->
           <typedef name="componentdef"
           classname="org.jboss.ant.types.component.ComponentDefinition"
           loaderRef="jboss.tasks.path"
           classpath="${jboss.tasks.path}"
           />
          
           <!-- The includes type -->
           <typedef name="includes"
           classname="org.jboss.ant.types.Includes"
           loaderRef="jboss.tasks.path"
           classpath="${jboss.tasks.path}"
           />
          
           <!-- The build targets type -->
           <typedef name="targets"
           classname="org.jboss.ant.types.target.TargetDefinitions"
           loaderRef="jboss.tasks.path"
           classpath="${jboss.tasks.path}"
           />
          
           <!-- TASKDEFS -->
          
           <!-- Update ide info for the main build -->
           <taskdef name="idemain"
           classname="org.jboss.ant.tasks.build.IDETask"
           loaderRef="jboss.tasks.path"
           classpath="${jboss.tasks.path}"
           />
          
           <!-- Update ide info for the component -->
           <taskdef name="idecomponent"
           classname="org.jboss.ant.tasks.component.IDETask"
           loaderRef="jboss.tasks.path"
           classpath="${jboss.tasks.path}"
           />
          
           <!-- DEFINITIONS -->
          
           <!-- The artifact types -->
           <artifacttype id="jar" outputtype="lib"/>
           <artifacttype id="api" outputtype="api"/>
          
           <!-- The default targets -->
           <targets id="targets">
          
           <!-- Build All -->
           <targetdef target="all" description="Build All">
           <main depends="build, doc, test, archives" components="none"/>
           <component depends="build, doc, test"/>
           </targetdef>
          
           <!-- Build -->
           <targetdef target="build" description="Build">
          
           <!-- Build the main release -->
           <main>
           <mkdir dir="@{releaseDir}"/>
           <antCall target="release"/>
           </main>
          
           <!-- Build the component -->
           <component>
           <mkdir dir="@{output}"/>
           </component>
          
           <!-- Compile the source -->
           <source>
           <mkdir dir="@{output}"/>
           <depend srcdir="@{sourcePath}" destdir="@{output}">
           <classpath>
           <pathelements/>
           </classpath>
           </depend>
           <javac srcdir="@{sourcePath}" destdir="@{output}">
           <classpath>
           <pathelements/>
           </classpath>
           </javac>
           </source>
          
           <!-- Create a jar archive -->
           <jar>
           <mkdir dir="@{parentDir}"/>
           <jar destfile="@{output}">
           <filesets/>
           </jar>
           </jar>
           </targetdef>
          
           <!-- Build the release -->
           <targetdef target="release">
          
           <!-- Copy the artifact into the release -->
           <artifact when="@{release}">
           <mkdir dir="@{release}"/>
           <copy todir="@{release}">
           <output/>
           </copy>
           </artifact>
           </targetdef>
          
           <!-- Build the release archives -->
           <targetdef target="archives">
          
           <!-- Make the archives -->
           <main>
          
           <!-- Create the zip file -->
           <zip destfile="@{output}/@{releaseName}.zip"
           basedir="@{releaseDir}"
           />
           </main>
           </targetdef>
          
           <!-- Documentation -->
           <targetdef target="doc" description="Documentation">
          
           <!-- Generate the documentation -->
           <component depends="api"/>
           </targetdef>
          
           <!-- Javadoc -->
           <targetdef target="api" description="Javadoc">
          
           <!-- Generate the javadoc -->
           <component/>
           <api>
           <mkdir dir="@{output}"/>
           <javadoc packagenames="*"
           destdir="@{output}"
           >
           <doctitle>
           <![CDATA[<h1>@{description} API Documentation</h1>]]>
           </doctitle>
           <bottom>
           <![CDATA[
           <i>
           <div align="center">
           <font size="-1">
           Copyright &#169; 2005 JBoss Inc. All Rights Reservered.
           </font>
           </div>
           </i>
           ]]>
           </bottom>
           <link href="http://java.sun.com/j2se/1.4.2/docs/api/"/>
           <sourcepath>
           <sourcepaths/>
           </sourcepath>
           <classpath>
           <sourcepathelements/>
           </classpath>
           </javadoc>
           </api>
           </targetdef>
          
           <!-- Clean the output -->
           <targetdef target="clean" description="Clean">
           <common>
           <delete dir="@{output}"/>
           </common>
           </targetdef>
          
           <!-- Clobber everything -->
           <targetdef target="clobber" description="Clobber">
           <main depends="clean">
           <delete dir="@{thirdparty}"/>
           </main>
           </targetdef>
          
           <!-- Synchronize -->
           <targetdef target="synchronize" description="Synchronize">
           <main components="none">
           <echo>FIXME cvsupdate ${basedir}</echo>
           <execant target="synchronize.components"/>
           <execant target="synchronize.main.after"/>
           </main>
           <component>
           <echo>FIXME cvsupdate ${basedir}</echo>
           <execant target="synchronize.component.after"/>
           </component>
           <artifact local="false">
           <echo>FIXME download/cvscheckout</echo>
           <mkdir dir="@{parentDir}"/>
           <get src="@{location}"
           dest="@{output}"
           useTimestamp="true"
           verbose="true"
           />
           </artifact>
           </targetdef>
          
           <!-- Commit -->
           <targetdef target="commit" description="Commit">
           <common>
           <echo>FIXME cvscommit</echo>
           </common>
           </targetdef>
          
           <!-- Test -->
           <targetdef target="test" description="Run the Tests">
           <component depends="build, runtest"/>
           </targetdef>
          
           <!-- Run the Test -->
           <targetdef target="runtest">
           <component/>
           <source when="@{test}">
           <mkdir dir="@{testDir}"/>
           <junit fork="true"
           printSummary="true">
           <formatter type="plain"/>
           <classpath>
           <pathElements/>
           </classpath>
           <batchtest todir="@{testDir}">
           <fileset dir="@{sourceDir}" includes="@{test}"/>
           </batchtest>
           </junit>
           </source>
           </targetdef>
           </targets>
          
           <!-- MACROS -->
          
           <!-- The execant macro -->
           <macrodef name="execant">
           <attribute name="dir"
           default="${basedir}"
           description="The directory"
           />
           <attribute name="target"
           description="The target"
           />
           <sequential>
           <!-- Invoke using a new ant -->
           <exec dir="@{dir}"
           executable="ant"
           >
           <arg line="@{target}"/>
           </exec>
           </sequential>
           </macrodef>
          
           <!-- The invoke macro -->
           <macrodef name="invoke">
           <attribute name="dir"
           default="${basedir}"
           description="The directory"
           />
           <attribute name="target"
           description="The target"
           />
           <sequential>
           <!-- Invoke using a new ant -->
           <ant dir="@{dir}" target="@{target}"/>
           </sequential>
           </macrodef>
          
           <!-- TARGETS -->
          
           <target name="rebuild" depends="synchronize" description="Synchronize then build">
           <execant target="build"/>
           </target>
          
           <target name="rebuildall" depends="synchronize" description="Synchronize then build all">
           <execant target="all"/>
           </target>
          
           <!-- After synchronization processing for the main build -->
           <target name="synchronize.main.after">
           <idemain/>
           </target>
          
           <!-- After synchronization processing for a component -->
           <target name="synchronize.component.after">
           <idecomponent/>
           </target>
          
           <target name="help">
           <fail message="Do not execute this build fragment directly!"/>
           </target>
          
          </project>
          
          


          The elements are as follows:

          typedef - this defines the classes that handle the declarations from the other files

          taskdef - standard stuff, in this case I have two custom task to generate ide files
          for the projects (one for the integration bulld, for the component)

          definition - this is an implementation detail. Rather than hardwiring what to do with
          each artifact, the artifacttype lets you override parameters like the output directory

          targetdef - this is where the real work is done, there are a number of different
          target types each inside a targetdef which I will explain in the next post.

          macrodef - these are just ant-1.6 macros which are helpers

          targets - some common targets that don't need to defined in the targetdefs (but they could be


          • 17. Re: NEW BUILD

            targets/targetdefs

            On the main build there was a reference to the targets

            <build id="JBossAS"
            ...
             targetdefs="targets">
            


            This defines a list of targetdefs and what each should do on the different portions
            of the build

            main - the top level integration build
            component - a component project
            common - convenience type when main and component are the same
            source - source targets, e.g. compilation
            artifact - these are per artifact type so you actually see jar and api rather than
            artifact

            Take a simple example:
             <!-- Clean the output -->
             <targetdef target="clean" description="Clean">
             <common>
             <delete dir="@{output}"/>
             </common>
             </targetdef>
            


            This says for top level and component builds we delete the output directory

            More complicated
            
             <!-- Build the release -->
             <targetdef target="release">
            
             <!-- Copy the artifact into the release -->
             <artifact when="@{release}">
             <mkdir dir="@{release}"/>
             <copy todir="@{release}">
             <output/>
             </copy>
             </artifact>
             </targetdef>
            


            For each artifact that has a release attribute, we copy it to that release location

            Probably the most complicated?
            
             <!-- Build -->
             <targetdef target="build" description="Build">
            
             <!-- Build the main release -->
             <main>
             <mkdir dir="@{releaseDir}"/>
             <antCall target="release"/>
             </main>
            
             <!-- Build the component -->
             <component>
             <mkdir dir="@{output}"/>
             </component>
            
             <!-- Compile the source -->
             <source>
             <mkdir dir="@{output}"/>
             <depend srcdir="@{sourcePath}" destdir="@{output}">
             <classpath>
             <pathelements/>
             </classpath>
             </depend>
             <javac srcdir="@{sourcePath}" destdir="@{output}">
             <classpath>
             <pathelements/>
             </classpath>
             </javac>
             </source>
            
             <!-- Create a jar archive -->
             <jar>
             <mkdir dir="@{parentDir}"/>
             <jar destfile="@{output}">
             <filesets/>
             </jar>
             </jar>
             </targetdef>
            


            On the top level build we create the release
            The component level is trivial
            The source level is just to compile it
            The artifact level involves jaring the referenced source classes

            The artifact definition
             <source id="main">
             <include input="test1.jar"/>
             <include input="jboss-common.jar"/>
             </source>
             <artifactdef artifact="test2.jar">
             <include input="main"/>
             </artifactdef>
            


            The source has an id main which the jar includes as its input

            The targetdef:
             <jar>
             <mkdir dir="@{parentDir}"/>
             <jar destfile="@{output}">
             <filesets/>
             </jar>
             </jar>
            


            This says take all the files sets that are the input to a jar artifact
            Each

            • 18. Re: NEW BUILD

              And this is the kind of targets that get generated:

              top level

              [ejort@htimes2 JBossAS]$ ant -projecthelp
              Buildfile: build.xml
              
              Main targets:
              
               all Build All for everything
               all.components Build All for all the components
               all.main Build All for the main build only
               all.test1 Build All for the component test1
               all.test2 Build All for the component test2
               api Javadoc for everything
               api.components Javadoc for all the components
               api.test1 Javadoc for the component test1
               api.test2 Javadoc for the component test2
               build Build for everything
               build.components Build for all the components
               build.main Build for the main build only
               build.test1 Build for the component test1
               build.test2 Build for the component test2
               clean Clean for everything
               clean.components Clean for all the components
               clean.main Clean for the main build only
               clean.test1 Clean for the component test1
               clean.test2 Clean for the component test2
               clobber Clobber for everything
               clobber.main Clobber for the main build only
               commit Commit for everything
               commit.components Commit for all the components
               commit.main Commit for the main build only
               commit.test1 Commit for the component test1
               commit.test2 Commit for the component test2
               doc Documentation for everything
               doc.components Documentation for all the components
               doc.test1 Documentation for the component test1
               doc.test2 Documentation for the component test2
               rebuild Synchronize then build
               rebuildall Synchronize then build all
               synchronize Synchronize for everything
               synchronize.components Synchronize for all the components
               synchronize.jboss-common.jar Synchronize for the artifact jboss-common.jar
               synchronize.junit.jar Synchronize for the artifact junit.jar
               synchronize.main Synchronize for the main build only
               synchronize.test1 Synchronize for the component test1
               synchronize.test2 Synchronize for the component test2
               test Run the Tests for everything
               test.components Run the Tests for all the components
               test.test1 Run the Tests for the component test1
               test.test2 Run the Tests for the component test2
              Default target: build
              


              component level
              [ejort@htimes2 test2]$ ant -projecthelp
              Buildfile: build.xml
              
              Main targets:
              
               all Build All
               api Javadoc
               api.test2.api Javadoc for the artifact test2.api
               build Build
               build.main Build for the source src/main
               build.test Build for the source src/test
               build.test2.jar Build for the artifact test2.jar
               clean Clean
               commit Commit
               doc Documentation
               rebuild Synchronize then build
               rebuildall Synchronize then build all
               synchronize Synchronize
               test Run the Tests
              Default target: build
              


              • 19. Re: NEW BUILD

                A basic critique (broad brush stuff)

                PROS of this approach:

                1) It is very declartive (though not very human readable)
                2) The inputs and outputs are clearly defined and readily available to tools
                3) The links between the components/artifacts are clearly defined (you can see what
                includes what)
                4) The declaritive approach makes the build easy to validate
                5) The build files are very small and simple

                CONS of this approach
                1) It has the same problem as buildmagic in that the process of the build is obfuscated
                (although I believe the notions involved can be easily learnt)
                2) The idea of an integration build doesn't sit well with the components also being
                a standalone project (they directly include the integeration project)

                <project name="project"
                 default="build"
                 basedir="."
                >
                 <!-- The main build -->
                 <import file="../JBossAS/build.xml"/>
                

                3) The ant typedef has some limitations which I have been able to workaround
                4) Internally it generates ant macros from the typedefs. This is not well defined
                in the ant documentation and I may have fallen foul of an undocmented feature.

                • 20. Re: NEW BUILD

                  Clarification. The targetdefs contain @ parameters. These are attributes
                  that come from each typedef,
                  e.g. test source is identified by a pattern to identify test case classes

                   <source id="test" test="**/*TestCase.java">
                   <include input="classes"/>
                   <include input="test.path"/>
                   </source>
                  


                  This is used in the target def for running tests
                   <!-- Run the Test -->
                   <targetdef target="runtest">
                   <component/>
                   <source when="@{test}">
                   <mkdir dir="@{testDir}"/>
                   <junit fork="true"
                   printSummary="true">
                   <formatter type="plain"/>
                   <classpath>
                   <pathElements/>
                   </classpath>
                   <batchtest todir="@{testDir}">
                   <fileset dir="@{sourceDir}" includes="@{test}"/>
                   </batchtest>
                   </junit>
                   </source>
                   </targetdef>
                  


                  Most of the attributes have reasonable defaults that can be overriden
                  integration wide on the build element or for each component/artifact.

                  • 21. Re: NEW BUILD

                     

                    "adrian@jboss.org" wrote:

                    ${somedir}/JBossAS - the main integration build
                    ${somedir}/test1 - test1 component
                    ${somedir}/test2 - test2 component
                    ${somedir}/tools - the tools directory containing jboss/tasks.xml


                    I notice that you declared jboss-common.jar as a dependency of JBossAS, so I assume you see some of the existing components essentially becoming thirdparty libraries of the AS -- being downloaded from the repository along with log4j. At the same time, other components (test1 & test2) are checked out of CVS and compiled from source.

                    Why the difference? Why not just have all the existing components become external libraries?

                    If all of the existing components were migrated to standalone projects, they could be integrated into the AS just like any thirdparty library. Their artifacts would be pulled from the repository just like log4j.



                    • 22. Re: NEW BUILD

                      Hi Ryan,

                      I don't anticipate that all builds will be standalone.

                      And certainly developers won't want 20-50 standalone projects that they have to build
                      separately, update the jars to some location then build the next until you get a final
                      project.

                      The idea of the build is that the developer can checkout the projects they want to
                      work on.
                      Where they aren't going to modify a project (or use a project under
                      development) they can just download the binary into thirdparty.
                      The projects they do want to work on, can be checked out from cvs as
                      source components.

                      For the nightly builds, cruise control could checkout all the projects as source
                      and rebuild the whole thing in one go.

                      In this example, the project is using the jboss-common.jar as a binary
                      but test1 and test2 are under development.

                      If I were to develop it further, I would add a local properties file where the
                      developer could specify which elements of the project they want as binary
                      and which they want the source/latest development version.
                      The default being as now (all components checked out as source).

                      • 23. Re: NEW BUILD

                        Just to clarify since none of the examples above has it,
                        it would be something like:

                        <build
                        cvsroot="cvs.sf.net/projects/jboss"
                        tag="Branch_3_2"
                        location="http://www.jboss.org/jboss-3.2/
                        >
                        ...
                        
                        <component id="common">
                         cvsmodule="common"
                         location="common"
                         <artifact id="jboss-common.jar"/>
                        </component>
                        ...
                        


                        Then the developer can choose whether the common module is checked out from
                        cvs or the artificats downloaded from a "versioned" repository.

                        • 24. Re: NEW BUILD

                           

                          "adrian@jboss.org" wrote:

                          And certainly developers won't want 20-50 standalone projects that they have to build
                          separately, update the jars to some location then build the next until you get a final
                          project.


                          Right, I agree this is not what we want. You shouldn't have to build all standalone projects to build JBAS. Instead, the build script should just download the 20-50 jar files for you.

                          "adrian@jboss.org" wrote:

                          In this example, the project is using the jboss-common.jar as a binary
                          but test1 and test2 are under development.


                          Ok, this makes sense. I agree that a developer should be able to check out specific dependencies and use the build artifacts from source rather than the downloaded binaries.

                          • 25. Re: NEW BUILD
                            pilhuhn

                            And the developer should not only be able to check out a source tree, but also be able to *update* the tree without throwing things away and re-checking out some modules. This not only saves bandwidth, but also time.

                            • 26. 3710409

                               

                              "pilhuhn" wrote:
                              And the developer should not only be able to check out a source tree, but also be able to *update* the tree without throwing things away and re-checking out some modules. This not only saves bandwidth, but also time.


                              Yes, that is the purpose of the build definition.
                              If you look at the synchronize method it actually does the following when executed
                              at the top level.

                              1) Synchronize the main build project (from cvs)
                              2) Reinvoke ant to pick up any new build.xml downloaded from cvs
                              3) Do the same for each component
                              (including checking out any new components that may have appeared in the build
                              definition)

                              With the current JBoss build, any new modules or thirdparty jars requires
                              the developer to look at CVSROOT/modules
                              then go to the relevent directory and do a "cvs co"
                              or blow away the whole thing and check out from scratch.

                              • 27. Re: NEW BUILD

                                The synchronize also regenerates any ide project files from the build definition
                                so all you have to do is refresh inside the ide (and maybe import new projects)

                                • 28. Re: NEW BUILD
                                  starksm64



                                  Max Rydahl Andersen wrote:

                                  > On Thu, 6 Jan 2005 22:41:46 +0100, Christian Bauer
                                  > <christian.bauer@jboss.com> wrote:
                                  >
                                  >> This looks like the right direction, subant and filelist is what we
                                  >> need.
                                  >>
                                  >> I might be intoxicated, but I actually think about using Maven. At
                                  >> least I'd like to have this feature (and it really looks like we all
                                  >> have to use Eclipse to standardize on our own dogfood): Maven can
                                  >> produce Eclipse .project and .classpath files automatically for you
                                  >> and there is a plugin that keeps your Eclipse configuration in sync
                                  >> with them. This would be killer if it includes code style settings
                                  >> etc. as well.
                                  >
                                  >
                                  > Please no! - not Maven ,)

                                  100% agree. I use Maven in my company and my feelings are :
                                  - maven just move the problems
                                  - the idea is cool, the implementation not
                                  - the plugins are not very well standardized
                                  - you'll have to rework some of the default plugins anyway to do what you want (the plugin itself or through a maven.xml file (kind of ant)

                                  >
                                  > If the only need/wish is for shared .project/.classpath then please
                                  > use the ant task that does that instead ! (there is a few of
                                  > these)

                                  +1

                                  >
                                  > But AFAIK these (both the Maven and the Ant based tasks) isn't
                                  > powerfull enough to be usable,( (and I *guess* this also goes for
                                  > intellij)
                                  >
                                  > The generated files will not be able to include refs to the src and
                                  > javadocs of the used .jars, thus I'll loose the ability to step
                                  > through the source code of the external libs.

                                  Actually it's quite easy to fix considering we're using a standardized thirdparty structure and naming convention (i did that for maven)

                                  >
                                  > And that will (in my world atleast) be a serious pain-in-the-* since I
                                  > would then need to recreate those links each time I "accidently"
                                  > runs the build
                                  > and overwriting my .classpath and .project.

                                  Plus, the automatic eclipse3 build don't really like some maven actions


                                  --
                                  Emmanuel Bernard
                                  emmanuel@hibernate.org
                                  callto://emmanuelbernard

                                  http://www.hibernate.org

                                  1 2 Previous Next