使用maven assembly插件生成OSGi捆绑包分发

使用maven assembly插件生成OSGi捆绑包分发,maven,osgi,distribution,maven-assembly-plugin,maven-resources-plugin,Maven,Osgi,Distribution,Maven Assembly Plugin,Maven Resources Plugin,我有一个多模块项目,其中每个模块都使用ApacheFelixMaven包插件打包为一个OSGi包。整个项目是使用列出上述模块的父POM构建的。某些模块包含配置资源(例如,属性文件),这些资源不应在捆绑包中进行部署,而应在专用配置文件夹中进行外部化。我的目标是创建一个分发文件夹(可能是一个zip文件),其外观如下: my-app-distribution /bundles module1-bundle.jar module2-bundle.jar

我有一个多模块项目,其中每个模块都使用ApacheFelixMaven包插件打包为一个OSGi包。整个项目是使用列出上述模块的父POM构建的。某些模块包含配置资源(例如,属性文件),这些资源不应在捆绑包中进行部署,而应在专用配置文件夹中进行外部化。我的目标是创建一个分发文件夹(可能是一个zip文件),其外观如下:

my-app-distribution
    /bundles
        module1-bundle.jar
        module2-bundle.jar
        etc.

    /conf
        external1.properties
        external2.properties
        etc.
<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2
      http://maven.apache.org/xsd/assembly-1.1.2.xsd">
<id>bin</id>

<!-- generate a ZIP distribution -->
<formats>
    <format>zip</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<baseDirectory>/</baseDirectory>

<moduleSets>
    <moduleSet>
        <!-- Enable access to all projects in the current multi-module build -->
        <useAllReactorProjects>true</useAllReactorProjects>

        <!-- select projects to include-->
        <includes>
            <include>myGroupId:myModuleArtifactId1</include>
            <include>myGroupId:myModuleArtifactId2</include>
            ...
        </includes>

        <!-- place bundle jars under /bundles folder in dist directory -->
        <binaries>
            <outputDirectory>${artifactId}/bundles</outputDirectory>
            <unpack>false</unpack>
        </binaries>
    </moduleSet>
</moduleSets>

<!-- now take files from ext-resources in this module and place them into dist /conf subfolder-->
<fileSets>
    <fileSet>
        <directory>ext-resources</directory>
        <outputDirectory>${artifactId}/conf/</outputDirectory>
        <includes>
            <include>*</include>
        </includes>
    </fileSet>

</fileSets>

</assembly>
<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>

<parent>
    <groupId>myGroupId</groupId>
    <artifactId>parentArtifactId</artifactId>
    <version>...</version>
</parent>

<groupId>myGroupId</groupId>
<artifactId>distribution</artifactId>
<version>...</version>

<packaging>pom</packaging>
<name>Distribution</name>
<description>This module creates the <MyProject> Distribution Assembly</description>
<url>http:...</url>

<!-- NOTE: These dependency declarations are only required to sort this project to the
     end of the line in the multi-module build.
-->
<dependencies>
    <dependency>
        <groupId>myGroupId</groupId>
        <artifactId>myModuleArtifactId1</artifactId>
        <version>${project.version}</version>
    </dependency>
 ...
</dependencies>

<build>
    <plugins>
        <plugin>
            <artifactId>maven-assembly-plugin</artifactId>
            <executions>
                <execution>
                    <id>dist-assembly</id>
                    <phase>package</phase>
                    <goals>
                        <goal>single</goal>
                    </goals>
                    <configuration>
                        <descriptors>
                            <descriptor>src/assemble/assembly.xml</descriptor>
                        </descriptors>
                    </configuration>
                </execution>
            </executions>
        </plugin>

    </plugins>
</build>
</project>
my-app-distribution
  /bundles
    module1-bundle.jar
    module2-bundle.jar
    etc.

  /conf
    external1.properties
    external2.properties
    etc. 
其中
/conf
目录下的属性文件是从各个模块的
/target
文件夹中手工挑选的文件。与src文件夹相比,
.properties
文件需要从目标文件夹中提取的原因是我正在使用Maven资源筛选,并且源属性文件包含环境特定值的
${..}
占位符。这些占位符在构建过程中得到正确解析-每个构建配置文件-并且
target/
文件夹包含实际的环境特定值

我已经做过很多次这样的分发文件操作-对于带有可执行JAR的分发,等等。在本例中,我想使用程序集描述符的“moduleSet”配置-使用moduleSet/binary描述符很容易将所有二进制文件/JAR拉入单个分发文件夹。在maven bundle插件中,也很容易将某些文件从打包到OSGi包中排除。我遇到的唯一问题是创建
/conf
分发文件夹并在那里收集必要的属性文件。我曾尝试在“moduleSet/sources”描述符中使用“fileset”,仅包含每个模块的
**/target
中的特定文件,但这似乎不起作用

有人有什么建议吗?一定有个简单的方法。或者我根本不应该使用

谢谢

简历


@PetrKozelka我不确定将特定于不同捆绑包的配置文件提取到单独的模块中是否是一个好主意。OSGi的全部要点在于捆绑包是独立的,并且可能是可重用的——无论是在开发还是在发行版中。在源代码中,将功能实现和相关配置文件分组在一起才有意义。对于特定的发行版,如果管理员需要控制某些参数,我可能需要提取一些文件。对于不同的分发/应用程序,这可能有所不同。程序集配置可能会更改,但捆绑包/源将保持不变。此外,每个捆绑包都可能单独开发和使用,并非所有捆绑包都必须始终是同一uber项目的一部分——正如您所设想的那样。您所建议的内容似乎属于按工件类型(例如“模型”、“服务”、“数据访问”、“配置”等)而不是按功能域/特性打包企业应用程序的同一旧类别。这种方法在单个应用程序/项目中运行正常,但在企业级失败,因为企业级通常需要重用垂直组件的子集(按功能域划分)


对于您依赖于模块中的文件布局的观点,我同意不应该存在这种依赖性。根据非常具体的发行版要求,可以通过文件的显式名称或命名约定手工挑选文件。(这正是我所面临的情况。)

我实际上已经想出了多少优雅的方法。在下面发布解决方案,以防其他人希望解决类似问题

摘要

我正在使用
maven汇编插件
从各个模块中提取二进制文件(bundle jar),并将它们打包到
/bundles
目录中。在某些资源文件应该外部化的每个模块中,我将这些文件合并到
/src/main/resources/external
目录下,并使用
maven resources plugin
在打包阶段将这些资源复制到我的专用
distribution
模块中的自动生成目录,该模块包含
assembly.xml
描述符文件,并且也是作为顶级项目的一部分构建的。在顶级项目构建的清理阶段,我在父POM中使用
maven clean plugin
来清除分发暂存目录的内容

MAVEN配置

在包含需要外部化的资源的每个捆绑包的模块POM中,我添加了以下资源管理配置:

 <build>
    <defaultGoal>install</defaultGoal>

    <!--
    enable resource filtering for resolving ${...} placeholders with environment-specific values 
    exclude any files that must be externalized
    -->
    <resources>
        <resource>
            <directory>src/main/resources</directory>
            <filtering>true</filtering>
            <excludes>
                <exclude>external/*.*</exclude>
            </excludes>
        </resource>
    </resources>
    ...

   <plugins>
        <!-- Copies contents of resources/external to dedicated folder defined by property in parent -->
        <!-- externalized resources will be packaged according to assembly instructions -->
        <plugin>
           <artifactId>maven-resources-plugin</artifactId>
           <version>2.6</version>
           <executions>
               <execution>
                   <id>copy-resources</id>
                   <phase>package</phase>
                   <goals>
                       <goal>copy-resources</goal>
                   </goals>
                   <configuration>
                       <outputDirectory>
                           ${project.parent.basedir}/${externalizableResourcesStageDir}
                       </outputDirectory>
                       <resources>
                           <resource>
                               <directory>src/main/resources/external</directory>
                               <filtering>true</filtering>
                           </resource>
                       </resources>
                   </configuration>
               </execution>
            </executions>
       </plugin>

        <!-- builds a JAR file for this bundle -->
        <plugin>
            <groupId>org.apache.felix</groupId>
            <artifactId>maven-bundle-plugin</artifactId>
            <extensions>true</extensions>
            <configuration>
                <instructions>
                    <Bundle-SymbolicName>${project.groupId}.${project.artifactId}</Bundle-SymbolicName>
                    <Import-Package>*</Import-Package>
                    <Export-Package>
                        ${project.groupId}.thismodulepackage*;version=${project.version}
                    </Export-Package>
                </instructions>
            </configuration>
        </plugin>
    </plugins>
</build>
assembly.xml
文件如下所示:

my-app-distribution
    /bundles
        module1-bundle.jar
        module2-bundle.jar
        etc.

    /conf
        external1.properties
        external2.properties
        etc.
<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2
      http://maven.apache.org/xsd/assembly-1.1.2.xsd">
<id>bin</id>

<!-- generate a ZIP distribution -->
<formats>
    <format>zip</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<baseDirectory>/</baseDirectory>

<moduleSets>
    <moduleSet>
        <!-- Enable access to all projects in the current multi-module build -->
        <useAllReactorProjects>true</useAllReactorProjects>

        <!-- select projects to include-->
        <includes>
            <include>myGroupId:myModuleArtifactId1</include>
            <include>myGroupId:myModuleArtifactId2</include>
            ...
        </includes>

        <!-- place bundle jars under /bundles folder in dist directory -->
        <binaries>
            <outputDirectory>${artifactId}/bundles</outputDirectory>
            <unpack>false</unpack>
        </binaries>
    </moduleSet>
</moduleSets>

<!-- now take files from ext-resources in this module and place them into dist /conf subfolder-->
<fileSets>
    <fileSet>
        <directory>ext-resources</directory>
        <outputDirectory>${artifactId}/conf/</outputDirectory>
        <includes>
            <include>*</include>
        </includes>
    </fileSet>

</fileSets>

</assembly>
<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>

<parent>
    <groupId>myGroupId</groupId>
    <artifactId>parentArtifactId</artifactId>
    <version>...</version>
</parent>

<groupId>myGroupId</groupId>
<artifactId>distribution</artifactId>
<version>...</version>

<packaging>pom</packaging>
<name>Distribution</name>
<description>This module creates the <MyProject> Distribution Assembly</description>
<url>http:...</url>

<!-- NOTE: These dependency declarations are only required to sort this project to the
     end of the line in the multi-module build.
-->
<dependencies>
    <dependency>
        <groupId>myGroupId</groupId>
        <artifactId>myModuleArtifactId1</artifactId>
        <version>${project.version}</version>
    </dependency>
 ...
</dependencies>

<build>
    <plugins>
        <plugin>
            <artifactId>maven-assembly-plugin</artifactId>
            <executions>
                <execution>
                    <id>dist-assembly</id>
                    <phase>package</phase>
                    <goals>
                        <goal>single</goal>
                    </goals>
                    <configuration>
                        <descriptors>
                            <descriptor>src/assemble/assembly.xml</descriptor>
                        </descriptors>
                    </configuration>
                </execution>
            </executions>
        </plugin>

    </plugins>
</build>
</project>
my-app-distribution
  /bundles
    module1-bundle.jar
    module2-bundle.jar
    etc.

  /conf
    external1.properties
    external2.properties
    etc. 

直接从子模块获取文件不是一个好主意,因为它容易出错——特别是当您更改文件布局等时。通常最好将配置附加为具有特定类型和分类器的辅助输出工件,然后将其用作依赖项。在您的情况下,可能需要一个模块来处理所有配置,或者将其放在发行版模块中。