使用maven assembly完美Docker化Java与C++混合工程

简介: 我们都知道基于maven的Java工程,使用`mvn package`命令即可实现构建,Docker化只需将构建结果COPY到镜像中就完成了,如果是Spring Boot工程,只需要拷贝一个jar进去。 但是,如果我们的工程是一个Java和C++混合的工程,Docker化就没有那么简单了。 C++构建的so文件不像Java构建的jar,可以直接复制到镜像中(只要镜像中的Java版本和构

我们都知道基于maven的Java工程,使用mvn package命令即可实现构建,Docker化只需将构建结果COPY到镜像中就完成了,如果是Spring Boot工程,只需要拷贝一个jar进去。

但是,如果我们的工程是一个Java和C++混合的工程,Docker化就没有那么简单了。

C++构建的so文件不像Java构建的jar,可以直接复制到镜像中(只要镜像中的Java版本和构建环境中的版本一致),so与操作系统环境上的很多因素有关,我们不敢贸然将实现构建好的so复制到镜像中。这就要求我们要将C++的源代码复制到镜像中,然后在镜像中构建,最后删除源代码。

随之而来的问题是,C++的源代码如何使用mvn命令一起打包?为什么会有这样的疑问呢?因为在持续集成/持续发布的流程中,从我们提交代码到工程以Docker镜像的形式上线,需要经历构建平台(阿里巴巴内部使用的是AONE)。我们通常用一条'`mvn'命令告诉构建平台构建Java,但面对混合工程,我们也许要写一堆脚本了。这样不优雅,这应该是我们的直觉,所以才有上述的问题。这个问题的答案是使用maven的assembly插件。

我们通过在工程根目录下的pom.xml中配置该插件:

<plugin>
    <artifactId>maven-assembly-plugin</artifactId>
    <version>2.6</version>
    <configuration>
        <finalName>${YOUR_MICRO_SERVICE_NAME}</finalName>
        <appendAssemblyId>false</appendAssemblyId>
        <descriptors>
            <descriptor>src/main/assembly/assembly.xml</descriptor>
        </descriptors>
    </configuration>
</plugin>

相应的assembly.xml如下:

<assembly>
    <id>assembly</id>
    <includeBaseDirectory>false</includeBaseDirectory>
    <formats>
        <format>dir</format>
    </formats>
    <fileSets>
        <fileSet>
            <includes>
                <include>${project.basedir}/${YOUR_JAVA_SRC_DIRECTORY}/target/${YOUR_JAR}</include>
            </includes>
            <outputDirectory>/</outputDirectory>
        </fileSet>
        <fileSet>
            <directory>${project.basedir}/${YOUR_CPP_SRC_DIRECTORY}</directory>
            <outputDirectory>/${CPP_DIRCTORY}</outputDirectory>
        </fileSet>
    </fileSets>
</assembly>

这样配置后,告诉构建平台执行mvn clean install assembly:assembly -DskipTests这个构建命令,然后到target/${YOUR_ARTIFACTID}这个构建输出目录下面tgz包即可。

这里,我踩过一个小坑。最初只在assembly.xml中定义了一个<fileSet>,然后通过定义多条<include>来打包jar和C++源代码。因为C++源代码只有一层目录:

<include>${project.basedir}/${YOUR_CPP_SRC_DIRECTORY}/*</include>

但没多久,C++的开发者根据业务逻辑,增加了一层目录,这还好,于是这个定义变成:

<include>${project.basedir}/${YOUR_CPP_SRC_DIRECTORY}/*</include>
<include>${project.basedir}/${YOUR_CPP_SRC_DIRECTORY}/*/*</include>

又没过几天,C++的源代码出现了4层目录,我石化了……所以才有了第二个<fileSet>。其实最初就应该这样设计,只是那个时间点觉得一个<fileSet>更优雅:(。

有了tgz包,我们的注意力就可以集中到Dockerfile的编写上了。依次执行如下步骤即可:

  1. 解压缩tgz
  2. 通过软连接处理32位和64位lib、so.xxx
  3. 进入C++源代码目录,执行make
  4. 复制构建好的so到/usr/lib64
  5. 删除tgz包,删除C++源代码目录
  6. 复制jar到指定位置
  7. 复制各种脚本,配置各种日志路径,修改目录或者文件的权限
  8. 使用VOLUME挂载日志等路径,以免镜像的新容器启动后丢失日志等文件
  9. 使用EXPOSE开放Docker容器的端口
  10. 使用ENV设定服务所需的环境变量
  11. 使用ENTRYPOINT执行启动脚本
目录
相关文章
|
4天前
|
Java Maven
Maven 构建 Java 项目
使用 Maven 的 archetype:generate 命令创建 Java 项目,如 `mvn archetype:generate` -DgroupId=com.companyname.bank -DartifactId=consumerBanking -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false,在 C:\MVN 下生成基于 maven 的 consumerBanking 项目。
|
8天前
|
Java C++
部落(pta)(并查集) Java以及C++
部落(pta)(并查集) Java以及C++
13 2
|
1天前
|
前端开发 Java 编译器
Object c/swift,java,c/c++在32位和64位各个平台上基本数据类型 所占有的字节数
Object c/swift,java,c/c++在32位和64位各个平台上基本数据类型 所占有的字节数
8 0
|
6天前
|
Java 数据库连接 Spring
K8S+Docker理论与实践深度集成java面试jvm原理
K8S+Docker理论与实践深度集成java面试jvm原理
|
7天前
|
Java Maven 开发者
Java一分钟之-Maven项目管理工具使用
【5月更文挑战第15天】Maven是Java开发的项目管理工具,用于自动化构建、依赖管理和项目信息管理。通过POM模型管理项目,依赖中央仓库。基本目录包括`src/main/java`、`src/main/resources`、`src/test/java`和`src/test/resources`。常用命令有`clean`、`compile`、`test`、`package`和`install`。面对依赖冲突、找不到依赖或编译错误,可以调整`pom.xml`或`settings.xml`。理解Maven的工作原理和解决常见问题能提升开发效率。
21 0
|
8天前
|
Java C++
愤怒的牛(java c++)(二分典型例子)
愤怒的牛(java c++)(二分典型例子)
10 1
|
8天前
|
存储 Java Maven
Maven 构建 Java 项目
使用 Maven 的 `maven-archetype-quickstart` 插件在 `C:\MVN` 创建 Java 应用项目 `consumerBanking`,命令行参数包括 `-DgroupId`, `-DartifactId` 和 `-DarchetypeArtifactId`。项目包含 src/main/java 和 src/test/java 目录,分别存放 Java 代码和测试代码,以及 src/main/resources 用于存储资源文件。默认生成的 `App.java` 和 `AppTest.java` 分别为应用主类和测试类。
|
8天前
|
数据采集 前端开发 Java
Java医院绩效考核系统源码maven+Visual Studio Code一体化人力资源saas平台系统源码
医院绩效解决方案包括医院绩效管理(BSC)、综合奖金核算(RBRVS),涵盖从绩效方案的咨询与定制、数据采集、绩效考核及反馈、绩效奖金核算到科到组、分配到员工个人全流程绩效管理;将医院、科室、医护人员利益绑定;全面激活人才活力;兼顾质量和效益、长期与短期利益;助力医院降本增效,持续改善、优化收入、成本结构。
23 0
|
8天前
|
移动开发 前端开发 Java
STS里的java 工程项目名称修改和目录设置成源代码
STS里的java 工程项目名称修改和目录设置成源代码
|
8天前
|
Kubernetes Java 调度
Java容器技术:Docker与Kubernetes
Java容器技术:Docker与Kubernetes
53 0