java - 在离线构建中缓存 Maven parent

标签 java maven docker

TL/DR:如何缓存 pom.xml文件的 <parent>所以我的构建可以在离线模式下运行?

我正在使用 Docker 构建一个 Maven 项目。我的目标是在构建中添加两个步骤:一个是下载所有依赖项,另一个是构建项目。到目前为止,这是我的 Dockerfile 的样子:

FROM maven:3.3-jdk-8

# Download the project dependencies (so they can be cached by Docker)
ADD pom.xml /runtime/
WORKDIR /runtime
RUN mvn dependency:go-offline
RUN mvn dependency:resolve-plugins

# Mount the local repository
ADD . /runtime

# Build the service
RUN mvn clean package -o -DskipTests

这似乎适用于插件。我检查了 /root/.m2/repository一切似乎都井井有条。

编辑:仔细检查 /root/.m2/repository 时目录,它不再存在。出于某种原因,Maven 没有将任何依赖项保存到此位置。

编辑 2:构建 Docker 镜像后,没有 /root/.m2/repository目录。但是,如果我运行 mvn dependency:go-offline从 Docker 容器内的 shell 中,可以毫无问题地创建目录。

当我尝试构建我的应用程序时,出现以下错误:

[ERROR] [ERROR] Some problems were encountered while processing the POMs:
[FATAL] Non-resolvable parent POM for com.example:service:1.2: Cannot access central (http://jcenter.bintray.com) in offline mode and the artifact org.springframework.boot:spring-boot-starter-parent:pom:1.4.0.M3 has not been downloaded from it before. and 'parent.relativePath' points at wrong local POM @ line 14, column 13
 @
[ERROR] The build could not read 1 project -> [Help 1]
[ERROR]
[ERROR]   The project com.sample:service:1.2 (/runtime/pom.xml) has 1 error
[ERROR]     Non-resolvable parent POM for com.oe:graph-service:1.2: Cannot access central (http://jcenter.bintray.com) in offline mode and the artifact org.springframework.boot:spring-boot-starter-parent:pom:1.4.0.M3 has not been downloaded from it before. and 'parent.relativePath' points at wrong local POM @ line 14, column 13 -> [Help 2]
[ERROR]
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR]
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/ProjectBuildingException
[ERROR] [Help 2] http://cwiki.apache.org/confluence/display/MAVEN/UnresolvableModelException

问题似乎是mvn dependency:go-offline没有解决 parent 。当我在离线模式下运行构建时,它中断了。

这是我的 pom.xml 的相关部分文件:

<?xml version="1.0" encoding="UTF-8"?>

<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/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>

    ...

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.4.0.M3</version>
    </parent>

    ...

    <repositories>
        <repository>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
            <id>central</id>
            <name>bintray</name>
            <url>http://jcenter.bintray.com</url>
        </repository>

        <repository>
            <id>repository.springsource.snapshot</id>
            <name>SpringSource Snapshot Repository</name>
            <url>http://repo.springsource.org/snapshot</url>
        </repository>

        <repository>
            <id>spring-milestones</id>
            <url>http://repo.spring.io/milestone</url>
        </repository>
    </repositories>

    <dependencies>
       ...

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-tomcat</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jetty</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.scala</groupId>
            <artifactId>spring-scala_2.11</artifactId>
            <version>1.0.0.BUILD-SNAPSHOT</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>
        <!-- disabling Spring cloud AWS until proper testing harnesses can be set up -->
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpcore</artifactId>
            <version>LATEST</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-aws-autoconfigure</artifactId>
            <version>1.1.0.RELEASE</version>
        </dependency>

        ...
    </dependencies>

    ...
</project>

最佳答案

如果您自定义 Maven 的 settings.xml 文件,您可以将存储库文件保存在图像上。

创建自定义版本的 settings.xml,修改 localRepository 设置,如下所示:

<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd">
  <!-- localRepository
   | The path to the local repository maven will use to store artifacts.
   |
   | Default: ${user.home}/.m2/repository -->
  <localRepository>/usr/share/maven/repo</localRepository>
...

然后在构建镜像时覆盖默认配置:

FROM maven:3-jdk-8

COPY settings.xml /usr/share/maven/conf/settings.xml

RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app

ADD . /usr/src/app

RUN mvn dependency:go-offline

RUN mvn clean package

现在您的存储库存储在 /usr/share/maven/repo 中。

使用构建

您还可以使用 ONBUILD 创建基本图像,这将允许为每个 Maven 项目自定义配置图像。

像这样:

FROM maven:3-jdk-8

COPY settings.xml /usr/share/maven/conf/settings.xml

RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app

ONBUILD ADD . /usr/src/app

ONBUILD RUN mvn dependency:go-offline

ONBUILD RUN mvn clean package

然后构建镜像:

docker build -t mvn_bldr .

这将为其他 Maven 图像创建一个模板。然后您可以创建自定义下游图像:

FROM mvn_bldr

如果您想进一步自定义您的图像,您可以添加更多指令,模板的每条指令都将在 FROM mvn_bldr 命令之后触发,如文档中所示:

The trigger will be executed in the context of the downstream build, as if it had been inserted immediately after the FROM instruction in the downstream Dockerfile.

关于java - 在离线构建中缓存 Maven parent,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40898608/

相关文章:

java - NetBeansUpdate 后无法编辑 JFrame 窗体

java - 检查 2 个数组以查看它们是否具有相同的值?

maven - 从 Maven 构建多模块项目到一个 war 文件中

python - 如何将kubernetes实现的 secret 环境变量获取到python中?

docker - 由于主机已满,在不同的驱动器上运行 docker 容器

java - 无法从我的 Android 应用程序 com.google.android.gms.auth.GoogleAuthException : Unknown 上传到谷歌驱动器

java - 在 JSP 中显示本地磁盘镜像(Web 上下文之外的镜像)

java - 使用 maven 插件将静态资源上传到 Amazon s3 服务器

java - maven POM中artifactId和name的区别

docker - 如何显示在 Docker 容器内运行的操作系统的 GUI?