25 May 2011

按照maven推荐的方式组装binary:

  1. 建一个子module
  2. packaging类型为pom
  3. 依赖需要被组装的子module
  4. true

但是在写assemble文件的时候,有个诡异的地方:似乎moduleSet的dependencySet并不是选择的某个module所依赖的。

比如有三个module:

  • com.honnix.demo:demo-core
  • com.honnix.demo:demo-api
  • com.honnix:demo:demo-service

其中demo-core runtime依赖slf4j,另外两个provided依赖;demo-core不依赖com.honnix.foo:bar,而另外两个compile依赖。

assemble文件大概是下面这个样子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
<assembly>
  ...
  <moduleSets>
    <moduleSet>
      <useAllReactorProjects>true</useAllReactorProjects>
      <includes>
        <include>com.honnix.demo:demo-core</include>
      </includes>
      <binaries>
        ...
        <dependencySets>
          <dependencySet>
            <outputDirectory>/dependencies</outputDirectory>
            <fileMode>0644</fileMode>
          </dependencySet>
        </dependencySets>
      </binaries>
    </moduleSet>
    <moduleSet>
      <useAllReactorProjects>true</useAllReactorProjects>
      <includes>
        <include>com.honnix.demo:demo-api</include>
        <include>com.honnix.demo:demo-service</include>
      </includes>
      <binaries>
        ...
        <dependencySets>
          <dependencySet>
            <outputDirectory>/dependencies</outputDirectory>
            <fileMode>0644</fileMode>
            <excludes>
              <exclude>com.honnix.foo:bar</exclude>
            </excludes>
          </dependencySet>
        </dependencySets>
      </binaries>
    </moduleSet>
  </moduleSets>
  ...
</assembly>

如果像上面这样写,slf4j最终会被当作runtime的依赖,而com.honnix.foo:bar也会被当作compile的依赖,尽管我已经声明exclude掉。

先说第二个问题,由于前面所说,dependenceSet包括了所有的依赖(包括这个assemble模块的依赖,以及所有传递依赖),所以即使分成两个moduleSet也不行,必须要为所有的moduleSet加上exclude:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
    ...
    <moduleSet>
      <useAllReactorProjects>true</useAllReactorProjects>
      <includes>
        <include>com.honnix.demo:demo-core</include>
      </includes>
      <binaries>
        ...
        <dependencySets>
          <dependencySet>
            <outputDirectory>/dependencies</outputDirectory>
            <fileMode>0644</fileMode>
            <excludes>
              <exclude>com.honnix.foo:bar</exclude>
            </excludes>
          </dependencySet>
        </dependencySets>
      </binaries>
    </moduleSet>
    ...

第一个问题其实也不是问题,这正是我期望的,slf4j被runtime依赖。但是换一种写法,如果只写一个moduleSet,结果就不同了:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<assembly>
  ...
  <moduleSets>
    <moduleSet>
      <useAllReactorProjects>true</useAllReactorProjects>
      <includes>
        <include>com.honnix.demo:demo-core</include>
        <include>com.honnix.demo:demo-api</include>
        <include>com.honnix.demo:demo-service</include>
      </includes>
      <binaries>
        ...
        <dependencySets>
          <dependencySet>
            <outputDirectory>/dependencies</outputDirectory>
            <fileMode>0644</fileMode>
            <excludes>
              <exclude>com.honnix.foo:bar</exclude>
            </excludes>
          </dependencySet>
        </dependencySets>
      </binaries>
    </moduleSet>
  </moduleSets>
  ...
</assembly>

像上面这样,slf4j最终会被当作provided依赖,而默认情况下provided依赖不会被组装,这就跟我想要的完全不同了。

没想明白为什么,但似乎maven-assembly-plugin处理moduleSet的依赖是这样的:

  • 依赖包括include的module的依赖,以及assemble module本身的依赖
  • include的module的依赖合并,算出一个依赖集,再加上assemble module本身的依赖
  • 一个moduleSet和多个在计算合并依赖的时候算法不同(这个有点废话,但不知道确定的行为是什么样子)

差不多就是这样吧,我已经写晕了。



blog comments powered by Disqus