2011-03-18 19 views
5

Attualmente sto cercando di sostituire il nostro ambiente di costruzione molto proprietario con Maven. La soluzione attuale è uno sviluppo interno per la build centrale, e per semplificare lo sviluppo locale compilo all'interno dell'IDE di Eclipse/Flex e ho uno script ANT che copia tutto insieme alla mia directory Apache locale (cioè il mio file ant non esegue la compilazione completa e si basa anche sull'avere tutti i progetti disponibili localmente).Usa Maven per creare un progetto Flex complesso

Utilizziamo Eclipse 3.6.1 (Helios) con Flash Builder Plugin (ad es. Flex4), destinato a Flex SDK 3.5 (FlashPlayer 10.0) con alcuni progetti sia di libreria .swc che di moduli .swf da caricare in runtime incluse risorse per ciascuno. Usiamo anche librerie esterne di linking/runtime (con un grosso sharedlibraries.swf che ha tutto dentro, cioè non c'è bisogno di avere i file .swc nella distribuzione). Ho installato Maven 3.0.2, usando Sonatypes flexmojos-maven-plugin 3.7.1 (come sembra più attivo di quello di Servebox). Ho creato manualmente i file pom per ogni progetto Eclipse, per assicurarmi che tutto funzioni e anche l'integrazione Eclipse-Maven sembra non avere il supporto Flex. Ho definito i parametri appropriati del compilatore e delle dipendenze in modo che tutti i singoli progetti vengano compilati correttamente, cioè i file .swf risultanti producono una versione funzionante della nostra applicazione. Ho letto anche il libro "Maven by Example" di Sonatype e ho guardato il loro "Maven: The Complete Reference", mentre facevo molti googling in parallelo.

Quello con cui sto combattendo è l'assemblaggio finale del mio progetto, nonché con ulteriori risorse (fogli di stile). Non capisco appieno "il modo Maven" e sospetto anche che Maven sia fortemente adattato per Java, lasciandomi un po 'in libertà con i miei progetti Flex.

Struttura di base dei miei progetti:

  • librerie esterne: ho aggiunto quelli con installazione: install-file per il mio repository, nessun problema qui
  • propri progetti di libreria: ognuno di loro producono una .swc artefatto che può essere consumato in altri progetti, con la gestione delle dipendenze di Maven che funziona correttamente, nessun problema qui
  • progetti di moduli swf: la nostra applicazione carica file swf in fase di esecuzione che a loro volta hanno alcune risorse aggiuntive di cui hanno bisogno (file stylesheet.swf, localizzati stringhe come singoli file .xlf, file di configurazione, ecc.). Sono quelli con cui sto lottando.

layout dei miei progetti SWF:

  • bin-debug/ usato da IDE costruisce, non utilizzati/ignorato dalla Maven costruire
  • src/ le fonti Flex (.as e file .mxml)
  • target/ Maven directory di destinazione
  • WebContent/ una directory con i file LETTO SUPPLEMENTARE che deve essere copiato l'artefatto destinazione (directory o file zip) testualmente, a fianco del manufatto .swf
  • stili/ file Flex .css che deve essere compilati in .swf fogli di stile, quelli sono artefatti aggiuntivi (uno per ogni css, per temi diversi) al swf progetto principale e il WebContent/contenuti

sto usando una gerarchia piatta per lavorare in Eclipse, vale a dire il mio file pom padrone è posto in una cartella che è un fratello di tutte le cartelle dei progetti.Esempio:

project_swf/src/... 
project_swf/WebContent/assets/labels.xlf 
project_swf/WebContent/config/config.xml 
project_swf/pom.xml 
lib_swc/src/... 
lib_swc/pom.xml 
master_build/pom.xml 
master_build/swf-assembly.xml 

sono riuscito a creare un 'maestro costruire' la costruzione di tutti i miei progetti SWC e SWF che utilizzano questo maestro pom:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 
    <modelVersion>4.0.0</modelVersion> 

    <name>Dragon Master Build</name> 
    <description>This project can be used to build and package the client application</description> 

    <properties> 
     <!-- this needs to be the same as the groupId tag, which unfortunately cannot be accessed directly using ${} notation --> 
     <group-id>de.zefiro.maven.example</group-id> 

     <!-- parameter to plugin swf files, shown as plugin 'Build Number' in client --> 
     <!-- TODO should be a build number on central system --> 
     <zefiro.plugin.buildno>local_dev_mvn</zefiro.plugin.buildno> 

     <!-- build all SWF files (except sharedlibraries.swf) with external references (Note: Flexmojo abuses the 'scope' concept here, but there is currently no better way) --> 
     <zefiro.swf.scope>external</zefiro.swf.scope> 
    </properties> 

    <groupId>de.zefiro.maven.example</groupId> 
    <artifactId>full_build</artifactId> 
    <version>1.0-SNAPSHOT</version> 
    <packaging>pom</packaging> 

    <build> 
     <sourceDirectory>src/</sourceDirectory> 
     <plugins> 
      <plugin> 
       <groupId>org.sonatype.flexmojos</groupId> 
       <artifactId>flexmojos-maven-plugin</artifactId> 
       <version>3.7.1</version> 
       <extensions>true</extensions> 
       <!-- We need to compile with Flex SDK 3.5 --> 
       <dependencies><dependency> 
        <groupId>com.adobe.flex</groupId> 
        <artifactId>compiler</artifactId> 
        <version>3.5.0.12683</version> 
        <type>pom</type> 
       </dependency></dependencies> 
       <!-- configuration for the Flex compilation --> 
       <configuration> 
        <targetPlayer>10.0.0</targetPlayer> 
        <incremental>false</incremental> 
        <debug>false</debug> 
        <runtimeLocales></runtimeLocales> 
        <locale>en_US</locale> 
        <optimize>true</optimize> 
        <showWarnings>true</showWarnings> 
        <strict>true</strict> 
        <useNetwork>true</useNetwork> 
        <allowSourcePathOverlap>true</allowSourcePathOverlap> 
        <definesDeclaration> 
         <property> 
          <name>ZEFIRO::META_INFO</name> 
          <value>"buildno=${zefiro.plugin.buildno}"</value> 
         </property> 
        </definesDeclaration> 
       </configuration> 
      </plugin> 
     </plugins> 
    </build> 

    <dependencies> 
     <dependency> 
      <groupId>com.adobe.flex.framework</groupId> 
      <artifactId>flex-framework</artifactId> 
      <version>3.5.0.12683</version> 
      <type>pom</type> 
      <exclusions> 
       <!-- make sure to exclude the default 'playerglobal' transitive dependency (which would be version 9 for SDK 3.5, however, we want version 10) --> 
       <exclusion> 
        <groupId>com.adobe.flex.framework</groupId> 
        <artifactId>playerglobal</artifactId> 
       </exclusion> 
      </exclusions> 
     </dependency> 

     <dependency> 
      <groupId>com.adobe.flex.framework</groupId> 
      <artifactId>playerglobal</artifactId> 
      <!-- this artifact version must match the flex SDK version used in this project --> 
      <version>3.5.0.12683</version> 
      <!-- the classifier specifies the target flash player major version (default is 9 for SDK 3.5) --> 
      <classifier>10</classifier> 
      <type>swc</type> 
     </dependency> 

     [... some more dependencies needed by all projects ...] 
    </dependencies> 

    <modules> 
     <module>../lib_swc</module> 
     <module>../project_swf</module> 
     [... calls all my projects ...] 
    </modules> 

</project> 

posso quindi compilare i miei progetti di libreria SWC con questo semplice POM:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> 
    <modelVersion>4.0.0</modelVersion> 

    <parent> 
     <groupId>de.zefiro.maven.example</groupId> 
     <artifactId>full_build</artifactId> 
     <version>1.0-SNAPSHOT</version> 
     <relativePath>../master_build</relativePath> 
    </parent> 

    <name>Sample library project</name> 
    <artifactId>lib_swc</artifactId> 
    <packaging>swc</packaging> 

    <dependencies> 
     <dependency> 
      <groupId>${group-id}</groupId> 
      <artifactId>some_other_library</artifactId> 
      <version>${project.version}</version> <!-- I should probably look into dependency/versioning as well, but for now this works --> 
      <!-- Note: no 'Scope' here, swc files will be build "merged into code"-style. Needed as transitive dependencies don't work with Maven/Flex - we use 'external' scope for the final swf projects dependencies --> 
      <type>swc</type> 
     </dependency> 
    </dependencies> 

</project> 

E il mio swf proietta con questo POM:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> 
    <modelVersion>4.0.0</modelVersion> 

    <parent> 
     <groupId>de.zefiro.maven.example</groupId> 
     <artifactId>full_build</artifactId> 
     <version>1.0-SNAPSHOT</version> 
     <relativePath>../master_build</relativePath> 
     </parent> 

    <name>Sample SWF module</name> 
    <artifactId>project_swf</artifactId> 
    <packaging>swf</packaging> 

    <build> 
    <!-- This name needs to be exactly specified, as the runtime will load it as it's specified in the configuration xml --> 
     <finalName>SampleProjectModule1</finalName> 

     <!-- define the master source file, it's picked up for some projects automatically and must be specified for others. Inherits compiler parameters from parent. --> 
     <plugin> 
      <groupId>org.sonatype.flexmojos</groupId> 
      <artifactId>flexmojos-maven-plugin</artifactId> 
      <version>3.7.1</version> 
      <configuration> 
       <sourceFile>project_swf_master_file.as</sourceFile> 
      </configuration> 
     </plugin> 

     <plugins> 
      <plugin> 
       <artifactId>maven-assembly-plugin</artifactId> 
       <configuration> 
        <descriptors> 
         <descriptor>../master_build/swf-assembly.xml</descriptor> 
        </descriptors> 
       </configuration> 
       <executions> 
        <execution> 
         <id>WebContent-packaging</id> 
         <phase>package</phase> 
         <goals><goal>single</goal></goals> 
        </execution> 
       </executions> 
      </plugin> 
     </plugins> 
    </build> 

    <dependencies> 
     <dependency> 
      <groupId>${group-id}</groupId> 
      <artifactId>project_swc</artifactId> 
      <version>${project.version}</version> 
      <scope>${zefiro.swf.scope}</scope> <!-- tell Flex Mojo that we want to compile using runtime shared libraries (rsl) --> 
      <type>swc</type> 
     </dependency> 
     [...] 
    </dependencies> 

</project> 

è la mia comprensione che ogni file POM genera un file di destinazione (specificati con l'etichetta di imballaggio) e che quando si usa il Flex mojo questo deve essere di formato SWF o SWC. Mi sembra di non essere in grado di specificare più target qui e ho anche faticato a ottenere i miei file di risorse inclusi (Flex copy-resources copia il wrapper html di cui non ho bisogno (per ogni progetto), il normale tag risorsa copia le risorse, ma non li impacchetta). Quello che ora è la mia attuale versione funzionante è specificare un proprio descrittore di assembly che raggruppa il file .swf di destinazione insieme alla cartella WebContent/in un file zip. Maven ha il supporto per i file jar/war/bin, ma quelli sembrano aspettarsi che certe condizioni siano vere, che non si applicano ai miei progetti Flex (ad es. Non ho un web.xml)

swf- assembly.xml:

<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd"> 
    <id>WebContent</id> 
    <formats> 
     <format>zip</format> 
    </formats> 
    <includeBaseDirectory>false</includeBaseDirectory> 
    <fileSets> 
     <!-- Take the base swf artifact (only, not the other stuff which is generated there) --> 
     <fileSet> 
      <directory>${project.build.directory}</directory> 
      <outputDirectory>/</outputDirectory> 
      <includes> 
       <include>*.swf</include> 
      </includes> 
     </fileSet> 
     <!-- add the WebContent folder --> 
     <fileSet> 
      <directory>FCPContent</directory> 
      <outputDirectory>/</outputDirectory> 
     </fileSet> 
    </fileSets> 
</assembly> 

Ora ho la directory di destinazione sia con il file .swf solo e un file zip contenente il file .swf insieme ai miei webcontent/risorse. Viene anche inserito nel repository Nexus al momento della chiamata 'mvn install', quindi questo sembra un buon passo avanti. Anche se sono felice di farlo completamente diverso se è meglio, il mio obiettivo finale è quello di avere una singola directory (o file zip/war che la contenga) con alcuni file statici (il nostro wrapper html e loader swf + configuration.xml), e per ciascuno dei nostri progetti swf (moduli che cariciamo in fase di esecuzione) una directory contenente i file .swf e il WebContent/risorse, ovvero il contenuto dei file zip che ora sono in grado di creare per ciascun progetto.

index.html 
loader.swf 
config.xml 
project_swf/SampleProjectModule1.swf 
project_swf/assets/labels.xlf 
project_swf/config/config.xml 
project2_swf/module2.swf 
project2_swf/cool_colors_stylesheet.swf 

Quindi la mia domanda sarebbe: come si fa a definire un tale progetto principale Maven che crea l'assemblaggio finale in questo formato? Se non c'è altro modo, un file ANT funzionante potrebbe essere accettabile, anche se ho letto che Maven ci spinge a stare lontano da quegli hack :)

Ho anche bisogno di compilare i file di fogli di stile che sono artefatti aggiuntivi per il progetti swf. Pubblicherò una domanda a parte per questo.

risposta

1

La mia soluzione è un po 'complessa e si sente' sporca '- ho pensato che ci potesse essere un modo più pulito, ma almeno ora ce l'ho fatta.

Fondamentalmente, sto usando il plugin Maven-assembly per creare archivi zip intermedi ("war" funziona ugualmente bene) contenente l'eseguibile swf insieme alle risorse statiche necessarie per ogni plugin che sto creando (noi usando un caricatore dinamico simile a OSGi simile a come funziona Eclipse, uno dei file statici è un plugin.xml, altri sono file di traduzione, nessuno di questi può essere incorporato nel file .swf). Maven memorizza il file .swf nella notazione del nome file di Maven come artefatto principale - cosa di cui sto completamente ignorando - e il mio archivio zip (con il nome .swf in base al tag finalName) accanto. Il file POM e assembly per questo funziona come mostrato nella mia domanda originale.

Ho aggiunto un progetto di assemblaggio vuoto che ha l'unico obiettivo di dipendere e quindi includere tutti i miei altri progetti. L'output di questo progetto è il mio ultimo artefatto "reale", che posso quindi utilizzare per la distribuzione e l'implementazione. Poiché non volevo raggruppare il mio spazio di lavoro Eclipse con troppi progetti di supporto, ho rotto la relazione 1: 1 dei progetti Maven e dei progetti Eclipse: il mio plug-in di assembly Maven risiede in un "assembly" di sottodirectory all'interno del mio progetto master_build. Ho aggiunto un'istruzione di modulo per questo nel mio master pom (master_build/pom.xml) che verrà eseguito nel reattore come ultimo progetto. (L'ordine viene eseguito automaticamente a causa delle dipendenze fornite - se lo si specifica come primo modulo e non viene eseguito per ultimo, si stanno costruendo progetti che non sono necessari :)

Ho anche realizzato i miei progetti di assemblaggio in POM un figlio di il mio padrone POM. Questo non è necessario, ma così facendo posso ereditare le proprietà Maven che ho definito. Inoltre eredita la chiamata al compilatore Flex, sebbene dal momento che non c'è nulla da compilare qui ciò non danneggia. YMMV.

Ecco il POM:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 
    <modelVersion>4.0.0</modelVersion> 

    <parent> 
     <groupId>de.zefiro.maven.example</groupId> 
     <artifactId>full_build</artifactId> 
     <version>1.0-SNAPSHOT</version> 
     <relativePath>../</relativePath> 
    </parent> 


    <groupId>${group-id}</groupId> 
    <artifactId>full_assembly</artifactId> 
    <name>Final Assembly</name> 
    <version>${project.parent.version}</version> 
    <packaging>pom</packaging> <!-- note that this is POM here, not war or zip --> 

    <build> 
     <plugins> 
      <plugin> 
       <artifactId>maven-assembly-plugin</artifactId> 
       <version>2.2.1</version> 
       <configuration> 
        <descriptors> 
         <descriptor>final-assembly.xml</descriptor> 
        </descriptors> 
       </configuration> 
       <executions> 
        <execution> 
         <id>Final-Packaging</id> 
         <phase>package</phase> 
         <goals> 
          <goal>single</goal> 
         </goals> 
        </execution> 
       </executions> 
      </plugin> 
     </plugins> 
    </build> 

    <dependencies> 
     <dependency> 
      <groupId>de.zefiro.maven.example</groupId> 
      <artifactId>wrapper</artifactId> 
      <version>1.0</version> 
      <type>war</type> 
     </dependency> 
     <dependency> 
      <groupId>${group-id}</groupId> 
      <artifactId>project_swf</artifactId> 
      <version>${project.version}</version> 
      <type>zip</type> 
      <classifier>WebContent</classifier> <!-- needs to be the ID of the assembler xml which packaged the zip file --> 
     </dependency> 
[... all other projects which should be packaged ...] 
    </dependencies> 
</project> 

seguito il descrittore di assemblaggio. Vedere lo assembly descriptor documentation per i dettagli.

<assembly 
    xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd"> 
    <id>FinalAssembly</id> 
    <formats> 
     <format>war</format> <!-- can be either zip or war, depending on what you wish --> 
    </formats> 
    <includeBaseDirectory>false</includeBaseDirectory> 
    <dependencySets> 
     <dependencySet> 
      <includes> 
       <include>de.zefiro.maven.example:wrapper:war:*</include> 
      </includes> 
      <unpack>true</unpack> 
     </dependencySet> 
     <dependencySet> 
      <includes> 
       <include>${group-id}:project_swf:zip:WebContent:${project.version}</include> 
      </includes> 
      <useProjectAttachments>true</useProjectAttachments> 
      <unpack>true</unpack> 
      <outputDirectory>sample_project_1</outputDirectory> 
     </dependencySet> 
[... list the same projects as in the POM file ...] 
    </dependencySets> 
</assembly> 

Ho un archivio che sto solo consumando, proveniente da un altro reparto. Contiene il wrapper HTML e l'applicazione Flex principale che viene eseguita (e in seguito carica tutti i miei plugin dalle sottodirectory in base a un file di configurazione e ai singoli metadati plugin.xml di progetti). Questo viene inserito nella directory root dell'archivio di output. Tutti gli altri progetti sono quelli che ho creato io stesso e vengono inseriti in singole sottodirectory, quindi non sto usando i jolly qui. Dal momento che voglio un singolo archivio contenente tutti i file uniti, utilizzo l'opzione disimballaggio di dependencySet.

Si noti che l'ID dichiarato nel descrittore di assemblaggio per i singoli progetti di plug-in swf viene ora utilizzato come classificatore nella sezione delle dipendenze del file pom nonché una parte della posizione di Maven nel descrittore di assieme. Lo stesso per il tipo di packacking, che ho scelto qui. Poiché questo è usato solo per gli archivi intermedi, zip va bene, per l'assemblaggio finale può essere scelto un formato diverso.

Ereditando dallo stesso genitore, posso riutilizzare le mie proprietà Maven, che sono anche disponibili nel descrittore dell'assembly.

Un nuovo progetto può essere aggiunto duplicando un progetto esistente e l'aggiunta a:

  • master_build/pom.xml come modulo
  • master_build/assemblaggio/pom.xml nella sezione dipendenze
  • master_build/assemblaggio/final-assembly.xml come dependencySet

Il manufatto finale è un file contenente la guerra:

012.351.
sample_project_1/SampleProjectModule1 
sample_project_1/assets/labels.xlf 
sample_project_1/config/config.xml 
other_data/configuration.xml 
application.swf 
index.html 

I.e. il contenuto di tutti i miei progetti swf nelle loro rispettive sottodirectory si è fuso con il contenuto del mio wrapper.war contenente i file statici.

può essere recuperato dal repository in questa posizione:

de.zefiro.maven.example:full_assembly:war:FinalAssembly:1.0-SNAPSHOT 

Per compilare i fogli di stile per ogni plugin che sto usando la stessa idea di base spostato verso il basso ad un livello di progetto individuale. Lo descriverò in the other questions

Open Problema: Non riesco a produrre entrambe le versioni di debug e di spedizione dei file. Potrei raddoppiare i progetti e comprimerli insieme (come faccio con i miei fogli di stile) oppure potrei eseguire l'intero reattore Maven (per il genitore POM e l'assieme master) due volte, ad es. diversi groupIds e quindi creare due percorsi completamente separati per tutti i progetti coinvolti. Non ho indagato ulteriormente su questo, però.

Problemi correlati