Using Maven for deployment

前端 未结 5 1453
小蘑菇
小蘑菇 2020-12-01 10:40

I have this task for the project with 4 nested subprojects using Maven:

  1. For each child: jar-up resource directory including project dependencies
  2. Move
相关标签:
5条回答
  • 2020-12-01 11:16

    Ok, I think the following might do what you need. The drawback of this approach is that there will be an interval between each deployment as the subsequent build is executed. Is this acceptable?

    Define a profile in each project with the same name (say "publish"). Within that profile you can define a configuration to use the antrun-plugin to deliver the files with FTP (see below).

    In the parent project you'll have a modules element, defining each project as a module. If you run mvn install -P publish, each project will be built in turn with the publish profile enabled, and the final artifact published to the target during the install phase. If you need to deploy additional files, modify the include element accordingly.

    Note the parameters for the FTP task have been set as properties, this allows them to be overridden from the command-line and/or inherited from the parent POM.

    <profiles>
      <profile>
        <id>publish</id>
        <plugin>
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-antrun-plugin</artifactId>
          <executions>
            <execution>
              <id>ftp</id>
              <phase>install</phase>
              <configuration>
                <tasks>
                  <ftp action="send" 
                      server="${ftp.host}" remotedir="${ftp.remotedir}" 
                      userid="${ftp.userid}" password="${ftp.password}" 
                      depends="${ftp.depends}" verbose="${ftp.verbose}">
                    <fileset dir="${project.build.directory}">
                      <include 
                        name="${project.build.finalName}.${project.packaging}"/>
                    </fileset>
                  </ftp>
                </tasks>
              </configuration>
              <goals>
                <goal>run</goal>
              </goals>
            </execution>
          </executions>
          <dependencies>
            <dependency>
              <groupId>commons-net</groupId>
              <artifactId>commons-net</artifactId>
              <version>1.4.1</version>
            </dependency>
            <dependency>
              <groupId>ant</groupId>
              <artifactId>ant-commons-net</artifactId>
              <version>1.6.5</version>
            </dependency>
            <dependency>
              <groupId>ant</groupId>
              <artifactId>ant-nodeps</artifactId>
              <version>1.6.5</version>
            </dependency>
          </dependencies>
        </plugin>
        <properties>
          <ftp.host>hostname</ftp.host>
          <ftp.remotedir>/opt/path/to/install</ftp.remotedir>
          <ftp.userid>user</ftp.userid>
          <ftp.password>mypassword</ftp.password>
          <ftp.depends>yes</ftp.depends>
          <ftp.verbose>no</ftp.verbose>          
        </properties>
      </profile>
    </profiles>
    

    Update: based on your comment: You could use the dependency plugin to download each dependency, except that a parent can't have a dependency on a child, and it will be built before the child. It would have to be another project. you also need to have somewhere the information for where to deploy them to. At the moment you have the target information in the individual projects so it isn't accessible in the deployer project.

    Taking this approach, you can define multiple profiles in the new project, one for each artifact. Each profile defines a dependency:copy execution to obtain the jar and an antrun execution for one of the projects. Common configuration (such as the dependencies for the antrun plugin) can be pulled out of the profiles. Also be aware that the properties will be merged if you define multiple profiles, so yo may need to qualify them with the artifact name, for example ftp.artifact1.host.

    <profiles>
      <profile>
        <id>deploy-artifact1</id>
        <plugin>
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-dependency-plugin</artifactId>
          <executions>
            <execution>
              <id>copy-dependency</id>
              <phase>prepare-package</phase>
              <goals>
                <goal>copy</goal>
              </goals>
              <configuration>
                <artifactItems>
                  <artifactItem>
                    <groupId>name.seller.rich</groupId>
                    <artifactId>artifact1</artifactId>
                    <version>1.0.0</version>
                    <type>jar</type>
                    <overWrite>false</overWrite>
                  </artifactItem>
                </artifactItems>
                <outputDirectory>${project.build.directory}/deploy-staging</outputDirectory>
                <overWriteReleases>false</overWriteReleases>
              </configuration>
            </execution>
          </executions>
        </plugin>
        <plugin>
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-antrun-plugin</artifactId>
          <executions>
            <execution>
              <id>ftp</id>
              <phase>install</phase>
              <configuration>
                <tasks>
                  <ftp action="send" 
                      server="${ftp.host}" remotedir="${ftp.remotedir}" 
                      userid="${ftp.userid}" password="${ftp.password}" 
                      depends="${ftp.depends}" verbose="${ftp.verbose}">
                    <fileset dir="${project.build.directory} includes="deploy-staging/"/>
                  </ftp>
                </tasks>
              </configuration>
              <goals>
                <goal>run</goal>
              </goals>
            </execution>
          </executions>
        </plugin>
        <properties>
          <!--if the properties differ between targets, qualify them with the artifact name-->
          <ftp.host>hostname</ftp.host>
          <ftp.remotedir>/opt/path/to/install</ftp.remotedir>
          <ftp.userid>user</ftp.userid>
          <ftp.password>mypassword</ftp.password>
          <ftp.depends>yes</ftp.depends>
          <ftp.verbose>no</ftp.verbose>          
        </properties>
      </profile>
    </profiles>  
    
    0 讨论(0)
  • 2020-12-01 11:18

    Does not work without passphrase.

        <profile>
            <id>publish</id>
            <build>
                <plugins>
                    <plugin>
                        <artifactId>maven-antrun-plugin</artifactId>
                        <executions>
                            <execution>
                                <id>scp</id>
                                <phase>deploy</phase>
                                <configuration>
                                    <tasks>
                                        <scp todir="user@host:some/remote/dir"
                                             sftp="true"
                                             keyfile="${user.home}/.ssh/devel-deploy.id_dsa"
                                             failonerror="false"
                                             verbose="true"
                                             passphrase="nopass"
                                        >
                                            <fileset dir="${project.build.directory}">
                                                <include
                                                    name="${project.build.finalName}.${project.packaging}"/>
                                            </fileset>
                                        </scp>
                                    </tasks>
                                </configuration>
                                <goals>
                                    <goal>run</goal>
                                </goals>
                            </execution>
                        </executions>
                        <dependencies>
                            <dependency>
                                <groupId>org.apache.ant</groupId>
                                <artifactId>ant-jsch</artifactId>
                                <version>1.9.4</version>
                            </dependency>
                        </dependencies>
                    </plugin>
                </plugins>
            </build>
        </profile>
    

    However, my favourite is

        <profile>
            <id>upload-devel</id>
            <build>
                <plugins>
                    <plugin>
                        <artifactId>maven-antrun-plugin</artifactId>
                        <executions>
                            <execution>
                                <id>upload-devel</id>
                                <phase>deploy</phase>
                                <configuration>
                                    <target>
                                        <exec executable="rsync" failonerror="false">
                                            <arg value="-aiz" />
                                            <arg value="${project.build.directory}/${project.artifactId}.${project.packaging}" />
                                            <arg value="user@host:some/remote/dir/." />
                                        </exec>
                                    </target>
                                </configuration>
                                <goals>
                                    <goal>run</goal>
                                </goals>
                            </execution>
                        </executions>
                    </plugin>
                </plugins>
            </build>
        </profile>
    

    though I don't know how compatible that is over different platforms.

    0 讨论(0)
  • 2020-12-01 11:20

    I would look at using the maven-assembly-plugin to do this.

    Something like this can be used to grab the files from the child projects and stuff them in output directories.

    <assembly>
      <id>xyzzy</id>
      <formats>
       <format>zip</format>
      </formats>
      <fileSets>
       <fileSet>
          <directory>../subproject1/target/</directory>
          <outputDirectory>/foo</outputDirectory>
          <includes>
            <include>*.jar</include>
          </includes>
       </fileSet>
       <fileSet>
          <directory>../subproject1/target/html-output/</directory>
          <outputDirectory>/foo</outputDirectory>
          <includes>
            <include>*.html</include>
            <include>*.js</include>
            <include>*.css</include>
          </includes>
        </fileSet>     
        <fileSet>
          <directory>../subproject2/target/</directory>
          <outputDirectory>/bar</outputDirectory>
          <includes>
            <include>**/**</include>
          </includes>
          <excludes>
            <exclude>**/*.exclude-this</exclude>
          </excludes>
        </fileSet>
      </fileSets> 
    </assembly>
    
    0 讨论(0)
  • 2020-12-01 11:30

    Maven is not really designed to deploy jars to a remote location; its main use is compiling and packaging artifacts. The assembly and dependency targets are primarily used to gather dependencies and files to package into an artifact.

    Having said that, maven does have a deploy goal which uses a component called wagon. This is primarily intended to deploy to a maven repository. There is a plugin called Cargo that can be used to deploy artifacts to a remote server, but that doesn't explode the jar contents by itself (it relies on the target app server to do all that). You might be able to extend the Maven Wagon functionality yourself.

    Also, it is possible to package a custom lifecycle, but that is getting into some pretty low level maven mojo (pun intended).

    0 讨论(0)
  • 2020-12-01 11:35

    Below POM will help to copy jar's file from project build directory to remote SFTP/FTP server.

    1. Use command mvn install -Dftp.password=password

    Since I want to pass password from command prompt for security reason, I have used -Dftp.password=password After execution of above command all the jar files from maven project target folder will be deployed in MAVEN folder on server.com

        <plugin>          <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-antrun-plugin</artifactId>
    
        <executions>
            <execution>
                <id>ftp</id>
                <phase>install</phase>
                <configuration>
                    <tasks>
                        <scp todir="user@server.com:/MAVEN/"
                            sftp="true" port="22" trust="true" password="${ftp.password}"
                            failonerror="false" verbose="true" passphrase="">
                            <fileset dir="${project.build.directory}">
                                <include name="*.jar" />
                            </fileset>
                        </scp>
                    </tasks>
                </configuration>
                <goals>
                    <goal>run</goal>
                </goals>
            </execution>
        </executions>
        <dependencies>
            <dependency>
                <groupId>org.apache.ant</groupId>
                <artifactId>ant-jsch</artifactId>
                <version>1.9.4</version>
            </dependency>
        </dependencies>
    
    </plugin>
    
    0 讨论(0)
提交回复
热议问题