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

主要分析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/目录下。

  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值