天天看點

關于maven插件的一點事(三)實踐

  • 關聯閱讀:
    • 關于maven插件的一點事(一)生命周期
    • 關于maven插件的一點事(二)插件
    • 關于maven插件的一點事(三)實踐

需求

需求:一個web項目,需要對其中某些jar包以及web代碼進行加密,為了節省資源以及友善起見,不影響本地開發,隻對用于測試和部署的war進行操作。

已知:加密程式是jar程式(但是還調用了 dll和so),隻能加密jar/war包裡的代碼,加密時要設定jar/war原始依賴(包括servlet.jar),原操作是手工解war裡的jar出來單個加密,再放回war包中。作為一個程式員,肯定是不能接受的,于是幫忙将其加入打包環節中。

思路

一種思路是對需要加密的jar先加密好,即war打包時下載下傳下來的jar已經是處理好的了,這樣子就很簡單,隻需要在package出jar之後進行一次處理,但是這樣子,開發環節可能會有問題,不過也好處理,隻需要在war包時處理版本的問題即可,即對引用的jar在打war時将依賴引用為加密的jar包。

一種思路是在打war包時,才對jar包進行處理。最終采用的是這個方案,雖然可能會影響自動打包的速度,但是主要是考慮到如下:

一是,對某些需要加密的jar我沒有打包權限,需要讓另外的人去另外打包,并且每次打包釋出到私服的時候要另外釋出加密的包。

二是,有一部分公共jar,每個war項目的秘鑰并不同,如果在jar包和war用的秘鑰不同,可能有問題。打war包時才對jar處理,這樣的話可以保證這兩者時一緻的。

操作

  • 首先要讓打包環節可以調用加密程式并且可以動态傳入一些參數進行加密,這個環節要走通,否則後面就無法操作了。
    • Maven不知道能否調用系統的

      java -jar

      ,但是我想到我之前使用ant是可以的,而ant可以直接用Maven調用,于是打算使用ant。
    • 測試發現,加密程式可以使用加密參數檔案和參數,于是把原先加密參數檔案中一些可能需要動态變換參數抽出來。如,依賴路徑、輸入和輸出。其他和加密有關的則作為一個

      common-encrypt.txt

      來傳入。
  • 依賴處理,由于加密程式需要指明依賴。于是第一次想到,用固定的lib,但是可能會有缺失;後面覺得還是用pom定義的依賴。找了下,插件

    maven-dependency-plugin

    copy-dependencies

    能滿足目标。于是使用。
  • 之後想到,要對某些dependency進行加密, 這些加密之後要替換掉原先的dependency,而加密程式需要的是原版的dependency以及不需要到打包裡的servlet.api,于是索性用兩次copy-dependencies産生兩個依賴檔案夾。一個是未處理的,一個是之後需要弄進打包裡的。
  • 但是原先打war包在package是自動的,好像不能控制依賴,于是找了一下,能不能自己控制哪些需要打到war包裡面,找到

    maven-assembly-plugin

    , 該插件可以自己定制打包,于是使用。之後我再用ant對定制後的産生的war包(部分依賴已加密)進行一次加密,即完成了目标。
  • 組合并調試上面提到的步驟,即實作了自動化加密。以後需要增加加密的依賴包,隻需要在 encrypt.xml把jar包名字加入即可。當然,增加了這些步驟之後,自動化打包的速度理所當然有所下降。
  • 相關的檔案(除加密)在下面

執行加密程式的ant任務

<?xml version="1.0" ?>
<project name="encrypt" default="encryptJar">
    <property name="jarPath" value="/usr/share/AxProtector/AxProtector.jar" />
    <property name="inputFileDir" value="${basedir}/scripts" />
    <property name="dependencyDir" value="${basedir}/target/dependencylibs" />
    <property name="targetLibDir" value="${basedir}/target/libs" />
	<property name="jar1Name" value="xxxxx-core" />
	<target name="encryptWar">
		<echo message=".........encrpyt encryptWar......." />
		<java fork="true" jar="${jarPath}">
			<arg value="-o:${basedir}/target/xxxxx-encrypted.war"></arg>
			<arg value="-jcp:${dependencyDir}" ></arg>
			<arg value="@${inputFileDir}/common-encrypt-info.xml"></arg>
			<arg value="${basedir}/target/xxxxx-assembly.war"></arg>
        </java>
	</target>
    <target name="encryptJar">
		<echo message=".........encrpyt ${jar1Name}......." />
        <java fork="true" jar="${jarPath}">
			<arg value="-o:${targetLibDir}/${jar1Name}-encrypted.jar"></arg>
			<arg value="-jcp:${dependencyDir}" ></arg>
			<arg value="@${inputFileDir}/common-encrypt-info.xml"></arg>
			<arg value="${dependencyDir}/${jar1Name}.jar"></arg>
        </java>
        <delete>
        	<file file="${targetLibDir}/${jar1Name}.jar"></file>
        </delete>
     </target>
</project>   
           

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>
	<artifactId>xxxxx</artifactId>
	<packaging>war</packaging>
	<parent>
		<groupId>com.xxx.xxxxx</groupId>
		<artifactId>xxxxx-root</artifactId>
		<version>3.0-SNAPSHOT</version>
		<relativePath>../../pom.xml</relativePath>
	</parent>

	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<uat.time>${maven.build.timestamp}</uat.time>
	</properties>

	<dependencies>
		......省略
	</dependencies>

	<build>

		<finalName>${artifactId}</finalName>
		<resources>
			<resource>
				<directory>${project.basedir}/src/main/resources</directory>
				<filtering>true</filtering>
			</resource>
		</resources>
		<plugins>
			<plugin>
				<artifactId>maven-compiler-plugin</artifactId>
				<version>3.3</version>
				<configuration>
					<source>1.8</source>
					<target>1.8</target>
					<encoding>UTF-8</encoding>
				</configuration>
			</plugin>
			        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-dependency-plugin</artifactId>
            <executions>
                <execution>
                    <id>copy-dependencies</id>
                    <phase>prepare-package</phase>
                    <goals>
                        <goal>copy-dependencies</goal>
                    </goals>
                    <configuration>
                        <outputDirectory>
                            ${project.build.directory}/libs
                        </outputDirectory>
                        <excludeArtifactIds>junit*,servlet*</excludeArtifactIds>
                        <excludeScope>provided</excludeScope>
                        <!-- 表示複制的jar檔案去掉版本資訊 -->  
                		<stripVersion>true</stripVersion> 
                    </configuration>
                </execution>
            </executions>
        </plugin>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-dependency-plugin</artifactId>
            <executions>
                <execution>
                    <id>copy-dependencies2</id>
                    <phase>prepare-package</phase>
                    <goals>
                        <goal>copy-dependencies</goal>
                    </goals>
                    <configuration>
                        <outputDirectory>
                            ${project.build.directory}/dependencylibs
                        </outputDirectory>
                        <!-- 表示複制的jar檔案去掉版本資訊 -->  
                		<stripVersion>true</stripVersion> 
                    </configuration>
                </execution>
            </executions>
        </plugin>
        <!-- 處理jar包和war包加密 -->
        <plugin>
          <artifactId>maven-antrun-plugin</artifactId>
          <version>1.8</version>
          <executions>
            <execution>
            	<id>ant-encryptJar</id>
              <phase>prepare-package</phase>
              <configuration>
                <target >
          				<ant antfile="encrypt.xml" target="encryptJar" inheritAll="false">
          				</ant>
                </target>
              </configuration>
              <goals>
                <goal>run</goal>
              </goals>
            </execution>
            <execution>
            	<id>ant-encryptWar</id>
              <phase>install</phase>
              <configuration>
                <target >
          				<ant antfile="encrypt.xml" target="encryptWar" inheritAll="false">
          				</ant>
                </target>
              </configuration>
              <goals>
                <goal>run</goal>
              </goals>
            </execution>
          </executions>
      </plugin>
        
      		<plugin>  
    			<artifactId>maven-assembly-plugin</artifactId>  
    			<configuration>  
       				<descriptor>scripts/assembly.xml</descriptor>  
   				</configuration>  
    			<executions>  
        			<execution>  
            			<id>make-assembly</id>  
            			<phase>package</phase>  
            			<goals>  
                			<goal>single</goal>  
            			</goals>  
       			 	</execution>  
				  </executions>  
			</plugin>
		</plugins>
	</build>
</project>
           

定義組裝的檔案

<assembly>  
  <id>assembly</id>  
  <formats>  
    <format>war</format>  
  </formats>  
  <includeBaseDirectory>false</includeBaseDirectory>  
  <dependencySets>  
  <!-- 将項目依賴的JAR包輸出到 WEB-INF/lib -->  
   <dependencySet>  
   		<excludes>
   			<exclude>*</exclude>
   		</excludes>
      <outputDirectory>WEB-INF/lib</outputDirectory>  
      <useProjectArtifact>true</useProjectArtifact>  
    </dependencySet>      
  </dependencySets>  
  <fileSets>  
    <fileSet>  
      <directory>${project.build.outputDirectory}</directory>  
      <outputDirectory>WEB-INF/classes</outputDirectory>  
    </fileSet>
    <fileSet>  
      <directory>${project.basedir}/target/libs</directory>  
      <outputDirectory>WEB-INF/lib</outputDirectory>  
    </fileSet>    
    <!-- 将 webapp 下的檔案輸出到 WAR 包 -->  
    <fileSet>  
      <directory>${project.basedir}/src/main/webapp</directory>  
      <outputDirectory>/</outputDirectory>  
    </fileSet>
  </fileSets>    
</assembly>