zeppelin源码分析(2)——distribution assembly过程分析

来源:互联网 发布:淘宝店运营计划书 编辑:程序博客网 时间:2024/04/30 13:04

主要分析zeppelin-distribution/target中的发布包的打包过程,即distribution目录结构中的bin、conf、Interpreter、lib等目录文件的来源。

1.1.1 parent pom

首先看一下${ZEPPELIN_HOME}/pom.xml文件中与package相关的几个重要的plugin的配置:

<plugin>  <artifactId>maven-dependency-plugin</artifactId>  <version>2.8</version>  <executions>    <execution>      <id>copy-dependencies</id>      <phase>process-test-resources</phase>      <goals>        <goal>copy-dependencies</goal>      </goals>      <configuration>        <outputDirectory>${project.build.directory}/lib</outputDirectory>        <overWriteReleases>false</overWriteReleases>        <overWriteSnapshots>false</overWriteSnapshots>        <overWriteIfNewer>true</overWriteIfNewer>        <includeScope>runtime</includeScope>      </configuration>    </execution>  </executions></plugin><plugin>  <artifactId>maven-jar-plugin</artifactId>  <version>2.4</version>  <configuration>    <archive>      <manifest>        <addClasspath>true</addClasspath>        <classpathPrefix>lib/</classpathPrefix>        <mainClass>theMainClass</mainClass>      </manifest>    </archive>  </configuration></plugin>

该pom作为parent pom,如下位置定义了这2个plugin

<build>  <plugins>
    <!-—上述plugin定义位置—->
  </plugins>
</build>

表示该项目所有的module都会默认继承使用这些plugin配置。有两点需要注意:

1)      maven-dependency-plugin的goal:copy-dependencies与maven的lifecycle的process-test-resourcesphase完成了绑定,意味着:mvn install或者package的时候,都会将内容的该module的runtime scope 的dependencies拷贝到target/lib目录下。

2)      maven-jar-plugin规定了生成META-INF/MANIFEST.MF文件的规范,添加classpath,并且从lib/目录中查找依赖(mainClass这里仅仅起占位作用,供sub-module override用)。

1.1.2 zeppelin-zengine的pom

zeppelin-zengine的pom并没有override任何与打包相关的plugin配置,故其采用默认的打包方式,即:target/目录下生成zeppelin-zengine-*.jar(*表示具体的版本,以下同)。并且,由于继承了parent pom的maven-dependency-plugin的配置,会将该module所有的dependencies拷贝到target/lib目录下。

1.1.3 zeppelin-interpreter pom

从“module间依赖关系”图可以看出,zeppelin针对各个语言的Interpreter实现类都依赖于zeppelin-interpreter module,该module的打包方式如下:

<plugin>  <groupId>org.apache.maven.plugins</groupId>  <artifactId>maven-shade-plugin</artifactId>  <version>2.3</version>  <configuration>    <artifactSet>      <includes>        <include>*:*</include>      </includes>    </artifactSet>    <filters>      <filter>        <artifact>*:*</artifact>        <excludes>          <exclude>META-INF/*.SF</exclude>          <exclude>META-INF/*.DSA</exclude>          <exclude>META-INF/*.RSA</exclude>        </excludes>      </filter>    </filters>  </configuration>  <executions>    <execution>      <phase>package</phase>      <goals>        <goal>shade</goal>      </goals>    </execution>  </executions></plugin>

采用shade plugin将该module所有runtime scope的依赖和该module编译后的artifact一起打包成一个fat jar(自包含的jar,即:该artifact和其所有的dependencies都被打包在一起)。

1.1.4 各Interpreter的pom

以hive interpreter为例,每个Interpreter的pom中dependencyplugin定义如下:

<plugin>  <artifactId>maven-dependency-plugin</artifactId>  <version>2.8</version>  <executions>    <execution>      <id>copy-dependencies</id>      <phase>package</phase>      <goals>        <goal>copy-dependencies</goal>      </goals>      <configuration>        <outputDirectory>${project.build.directory}/../../interpreter/hive</outputDirectory>        <overWriteReleases>false</overWriteReleases>        <overWriteSnapshots>false</overWriteSnapshots>        <overWriteIfNewer>true</overWriteIfNewer>        <includeScope>runtime</includeScope>      </configuration>    </execution>    <execution>      <id>copy-artifact</id>      <phase>package</phase>      <goals>        <goal>copy</goal>      </goals>      <configuration>        <outputDirectory>${project.build.directory}/../../interpreter/hive</outputDirectory>        <overWriteReleases>false</overWriteReleases>        <overWriteSnapshots>false</overWriteSnapshots>        <overWriteIfNewer>true</overWriteIfNewer>        <includeScope>runtime</includeScope>        <artifactItems>          <artifactItem>            <groupId>${project.groupId}</groupId>            <artifactId>${project.artifactId}</artifactId>            <version>${project.version}</version>            <type>${project.packaging}</type>          </artifactItem>        </artifactItems>                    </configuration>    </execution>  </executions></plugin>

可以看出,每个Interpreter的编译后,会将该Interpreter的runtime scope的依赖和该Interpreter编译后的artifact 一起拷贝到${project.build.directory}/../../interpreter/hive目录,该目录实际上对应到${ZEPPELIN_HOME}/interpreter/xxx目录下。

除了zeppelin-spark相关的几个module(zeppelin-display、zeppelin-zinterpreter、zeppelin-spark-dependencies)之外,余下所有的zeppelin的Interpreter具体实现,都与hive的打包方式相同。

1.1.5 zeppelin-server的pom

与zeppelin-zengine相同,zeppelin-server也没有override parent pom中与打包相关的plugin配置,故其编译后会在target/目录下生成zeppelin-zengine-*.jar。并且由module之间依赖图可以看出:


zeppelin-server直接依赖于zeppelin-zengine,zeppelin-interpreter又是zeppelin-zengine的直接依赖,这样zeppelin-interpreter就是zeppelin-server的间接依赖。maven在打包时会将zeppelin-zengine-*.jar和zeppelin-interpreter-*.jar拷贝到target/lib/目录下。zeppelin-server可以与传统应用系统开发中的“业务逻辑层”对应,该module中主要实现对REST和WebSocket消息的业务封装,权限控制等业务逻辑。zeppelin-zengine类似于“DAO和底层webSocket消息通信协议解析“等,zeppelin-interpreter专门用来处理以独立进程启动各种interpreter,以及与zeppelin-engine之间的RPC通信问题(实际是基于Socket的IPC,采用Thrift协议)。

1.1.6 zeppelin-web的pom

zeppelin-web module的package为war,默认绑定的是maven-war-plugin的war goal。

<plugin>  <groupId>org.apache.maven.plugins</groupId>  <artifactId>maven-war-plugin</artifactId>  <configuration>    <warSourceDirectory>dist</warSourceDirectory>    <webXml>dist\WEB-INF\web.xml</webXml>  </configuration></plugin>

zeppelin-web全部采用的是html+js(angularJS)实现,web中并没有需要预先编译的后端代码,这里warSourceDirectory定义了web页面、js脚本和相关资源的目录,该目录中的文件会被打包到最后的zeppelin-web-*.war包中,该目录的内容来自于zeppelin-web/src/目录。webXml定义了web.xml文件的位置。

1.1.7 zeppelin-distribution的assembly/distribution.xml分析

zeppelin-distribution采用了maven-assembly-plugin来自定义其打包格式,该格式由zeppelin-distribution/src/assembly/distribution.xml来规定:

<dependencySets>  <dependencySet>    <!-- Enable access to all projects in the current multimodule build!    <useAllReactorProjects>true</useAllReactorProjects> -->    <!-- Now, select which projects to include in this module-set. -->    <includes>      <include>org.apache.zeppelin:zeppelin-server</include>      <include>org.apache.zeppelin:zeppelin-web</include>    </includes>    <useProjectArtifact>false</useProjectArtifact>    <useTransitiveDependencies>false</useTransitiveDependencies>  </dependencySet>  <dependencySet>    <outputDirectory>/lib</outputDirectory>    <useProjectArtifact>false</useProjectArtifact>    <excludes>      <exclude>${project.groupId}:zeppelin-web</exclude>      <exclude>${project.groupId}:zeppelin-server</exclude>    </excludes>  </dependencySet></dependencySets>

该段定义了2个dependencySet:

1)      第1个dependencySet定义如下:

<include>org.apache.zeppelin:zeppelin-server</include>
<include>
org.apache.zeppelin:zeppelin-web</include>

规定了最后的打包格式(dir、tar.gz)中包含哪些artifact。该dependencySet与pom中定义的dependency(如下)相配合:

<!-- NOTE: These dependency declarations are only required to sort this project to the     end of the line in the multimodule build.  --><dependencies>  <dependency>    <artifactId>zeppelin-server</artifactId>    <groupId>${project.groupId}</groupId>    <version>${project.version}</version>  </dependency>  <dependency>    <artifactId>zeppelin-web</artifactId>    <groupId>${project.groupId}</groupId>    <version>${project.version}</version>    <type>war</type>  </dependency></dependencies>

解决直接dependency和间接dependency的打包问题(其实zeppelin-distribution由于不含任何代码,所以编译并不需要任何依赖,这里引入这2个dependency主要是为了自定义打包问题)。

由于zeppelin-distribution这个module本身并不含有任何源码需要编译后发布,故它自身不应该被包含在最后的打包文件中。故定义:

<useProjectArtifact>false</useProjectArtifact><useTransitiveDependencies>false</useTransitiveDependencies>

避免引入zeppelin-distribution这个空的artifact以及它的dependencies。

2)      第2个dependencySet定义为将第一个dependencySet include的2个artifact zeppelin-server和zeppelin-web的依赖,全部打包的lib/目录下。

0 0