LoongArch64 (loong64) 龙芯架构:构建 Maven 依赖问题处理

前景提要

之前测试过一些电脑硬件、操作系统 Maven 编译时的性能对比:苹果 Apple MacBook M4 效率对比

最近刚入手一台龙芯电脑,于是测试一下 Maven 构建,发现有些 Java 项目在传统 CPU(amd64、arm64 等)可以正常编译构建,但是在龙芯上无法正常编译

问题发现

在龙芯 3A5000 执行 Nacos 2.5.0 标签编译时,出现异常

由下方异常可知,Maven 编译时,从 Maven 中央仓库(个人使用了国内腾讯云的 Maven 代理仓库)下载 kr.motd.maven:os-maven-plugin:1.5.0.Final 使用,然后 kr.motd.maven:os-maven-plugin:1.5.0.Final 无法识别龙芯架构。

kr.motd.maven:os-maven-plugin 的作用就是根据操作系统的名称,获取操作系统的架构。

及时升级到当前最新版 kr.motd.maven:os-maven-plugin:1.7.1 2022-11-07 发布,也无法解决此问题

[root@anolis nacos]# mvn -e -V clean install -Dmaven.test.skip=true
Apache Maven 3.9.16 (2bdd9fddda4b155ebf8000e807eb73fd829a51d5)
Maven home: /srv/apache-maven-3.9.16
Java version: 1.8.0_492, vendor: Oracle Corporation, runtime: /srv/jdk8u492-b09/jre
Default locale: zh_CN, platform encoding: UTF-8
OS name: "linux", version: "6.6.102-5.3.3.an23.loongarch64", arch: "loongarch64", family: "unix"
[INFO] Error stacktraces are turned on.
[INFO] Scanning for projects...
Downloading from cloud-tencent: https://mirrors.cloud.tencent.com/nexus/repository/maven-public/kr/motd/maven/os-maven-plugin/1.5.0.Final/os-maven-plugin-1.5.0.Final.pom
Downloaded from cloud-tencent: https://mirrors.cloud.tencent.com/nexus/repository/maven-public/kr/motd/maven/os-maven-plugin/1.5.0.Final/os-maven-plugin-1.5.0.Final.pom (6.4 kB at 7.9 kB/s)
Downloading from cloud-tencent: https://mirrors.cloud.tencent.com/nexus/repository/maven-public/kr/motd/maven/os-maven-plugin/1.5.0.Final/os-maven-plugin-1.5.0.Final.jar
Downloaded from cloud-tencent: https://mirrors.cloud.tencent.com/nexus/repository/maven-public/kr/motd/maven/os-maven-plugin/1.5.0.Final/os-maven-plugin-1.5.0.Final.jar (29 kB at 43 kB/s)
[INFO] ------------------------------------------------------------------------
[INFO] Detecting the operating system and CPU architecture
[INFO] ------------------------------------------------------------------------
[INFO] os.detected.name: linux
[INFO] os.detected.arch: unknown
[INFO] os.detected.version: 6.6
[INFO] os.detected.version.major: 6
[INFO] os.detected.version.minor: 6
[ERROR] unknown os.arch: loongarch64 -> [Help 1]
org.apache.maven.MavenExecutionException: unknown os.arch: loongarch64
    at kr.motd.maven.os.DetectExtension.afterProjectsRead (DetectExtension.java:95)
    at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:223)
    at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:173)
    at org.apache.maven.DefaultMaven.execute (DefaultMaven.java:101)
    at org.apache.maven.cli.MavenCli.execute (MavenCli.java:919)
    at org.apache.maven.cli.MavenCli.doMain (MavenCli.java:285)
    at org.apache.maven.cli.MavenCli.main (MavenCli.java:207)
    at sun.reflect.NativeMethodAccessorImpl.invoke0 (Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke (NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke (Method.java:498)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced (Launcher.java:255)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launch (Launcher.java:201)
    at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode (Launcher.java:362)
    at org.codehaus.plexus.classworlds.launcher.Launcher.main (Launcher.java:314)
[ERROR] 
[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/MavenExecutionException
[root@anolis nacos]#

解决方案

龙芯 Maven 仓库

  1. 龙芯平台Java应用迁移指南 · 文档
  2. https://maven.loongnix.cn/loongarchabi1/maven/:龙芯 Maven 仓库(兼容Linux 4.19内核)
  3. https://maven.loongnix.cn/loongarch/maven/:龙芯 Maven 仓库(兼容Linux5.10.0内核及以上)

龙芯官方针对于 无法在龙芯CPU中运行的 Maven 依赖进行了独立编译,并发布到龙芯自己的 Maven 仓库

在重新编译前,需要先删除本地 Maven 依赖 kr.motd.maven:os-maven-plugin:1.5.0.Final(从 Maven 中央仓库下载的依赖),编译时,由于设置了 pluginRepositoriesrepositories,所以会优先从龙芯官方 Maven 仓库中下载

<pluginRepositories>
    <pluginRepository>
        <id>loongarch</id>
        <name>Loongnix Maven Repository</name>
        <url>https://maven.loongnix.cn/loongarch/maven/</url>
        <releases>
            <enabled>true</enabled>
        </releases>
        <snapshots>
            <!-- 通常只需要 release 版本 -->
            <enabled>false</enabled>
        </snapshots>
    </pluginRepository>
</pluginRepositories>

<repositories>
    <repository>
        <id>loongarch</id>
        <name>Loongnix Maven Repository</name>
        <url>https://maven.loongnix.cn/loongarch/maven/</url>
        <releases>
            <enabled>true</enabled>
        </releases>
        <snapshots>
            <!-- 通常只需要 release 版本 -->
            <enabled>false</enabled>
        </snapshots>
    </repository>
</repositories>

作者个人环境变量配置:MAVEN_OPTS=-Dmaven.repo.local=/srv/apache-maven-repo,即:将本地 Maven 仓库地址设置为 /srv/apache-maven-repo,优先级高于 settings.xml 中的 <localRepository>/path/to/local/repo</localRepository>

# 查看本地存在的不支持 龙芯 的依赖
find /srv/apache-maven-repo/kr/motd/maven/os-maven-plugin/
# 删除本地存在的不支持 龙芯 的依赖
rm -rf /srv/apache-maven-repo/kr/motd/maven/os-maven-plugin/*
# 确认删除
find /srv/apache-maven-repo/kr/motd/maven/os-maven-plugin/
mvn -e -V clean install -Dmaven.test.skip=true

# 如果其他依赖也存在不兼容的情况,请同时删除依赖后再执行打包
[root@anolis nacos]# find /srv/apache-maven-repo/kr/motd/maven/os-maven-plugin/
/srv/apache-maven-repo/kr/motd/maven/os-maven-plugin/
/srv/apache-maven-repo/kr/motd/maven/os-maven-plugin/1.5.0.Final
/srv/apache-maven-repo/kr/motd/maven/os-maven-plugin/1.5.0.Final/os-maven-plugin-1.5.0.Final.jar.sha1
/srv/apache-maven-repo/kr/motd/maven/os-maven-plugin/1.5.0.Final/_remote.repositories
/srv/apache-maven-repo/kr/motd/maven/os-maven-plugin/1.5.0.Final/os-maven-plugin-1.5.0.Final.pom.sha1
/srv/apache-maven-repo/kr/motd/maven/os-maven-plugin/1.5.0.Final/os-maven-plugin-1.5.0.Final.pom
/srv/apache-maven-repo/kr/motd/maven/os-maven-plugin/1.5.0.Final/os-maven-plugin-1.5.0.Final.jar
[root@anolis nacos]# rm -rf /srv/apache-maven-repo/kr/motd/maven/os-maven-plugin/*
[root@anolis nacos]# find /srv/apache-maven-repo/kr/motd/maven/os-maven-plugin/
/srv/apache-maven-repo/kr/motd/maven/os-maven-plugin/
[root@anolis nacos]# mvn -e -V clean install -Dmaven.test.skip=true
Apache Maven 3.9.16 (2bdd9fddda4b155ebf8000e807eb73fd829a51d5)
Maven home: /srv/apache-maven-3.9.16
Java version: 1.8.0_492, vendor: Oracle Corporation, runtime: /srv/jdk8u492-b09/jre
Default locale: zh_CN, platform encoding: UTF-8
OS name: "linux", version: "6.6.102-5.3.3.an23.loongarch64", arch: "loongarch64", family: "unix"
[INFO] Error stacktraces are turned on.
[INFO] Scanning for projects...
Downloading from loongarch: https://maven.loongnix.cn/loongarch/maven/kr/motd/maven/os-maven-plugin/1.5.0.Final/os-maven-plugin-1.5.0.Final.pom
Downloaded from loongarch: https://maven.loongnix.cn/loongarch/maven/kr/motd/maven/os-maven-plugin/1.5.0.Final/os-maven-plugin-1.5.0.Final.pom (6.7 kB at 14 kB/s)
Downloading from loongarch: https://maven.loongnix.cn/loongarch/maven/kr/motd/maven/os-maven-plugin/1.5.0.Final/os-maven-plugin-1.5.0.Final.jar
Downloaded from loongarch: https://maven.loongnix.cn/loongarch/maven/kr/motd/maven/os-maven-plugin/1.5.0.Final/os-maven-plugin-1.5.0.Final.jar (29 kB at 333 kB/s)
[INFO] ------------------------------------------------------------------------
[INFO] Detecting the operating system and CPU architecture
[INFO] ------------------------------------------------------------------------
[INFO] os.detected.name: linux
[INFO] os.detected.arch: loongarch_64
[INFO] os.detected.version: 6.6
[INFO] os.detected.version.major: 6
[INFO] os.detected.version.minor: 6
[INFO] os.detected.release: anolis
[INFO] os.detected.release.version: 23.4
[INFO] os.detected.release.like.anolis: true
[INFO] os.detected.classifier: linux-loongarch_64
[WARNING] The project com.alibaba.nacos:nacos-all:pom:2.5.0 uses prerequisites which is only intended for maven-plugin projects but not for non maven-plugin projects. For such purposes you should use the maven-enforcer-plugin. See https://maven.apache.org/enforcer/enforcer-rules/requireMavenVersion.html
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Build Order:
[INFO] 
[INFO] Alibaba NACOS 2.5.0                                                [pom]
[INFO] nacos-api 2.5.0                                                    [jar]
[INFO] nacos-common 2.5.0                                                 [jar]
[INFO] nacos-consistency 2.5.0                                            [jar]
[INFO] nacos-plugin 2.5.0                                                 [pom]
[INFO] nacos-datasource-plugin 2.5.0                                      [jar]
[INFO] nacos-custom-environment-plugin 2.5.0                              [jar]
[INFO] nacos-sys 2.5.0                                                    [jar]
[INFO] nacos-persistence 2.5.0                                            [jar]
[INFO] nacos-auth-plugin 2.5.0                                            [jar]
[INFO] nacos-auth 2.5.0                                                   [jar]
[INFO] nacos-trace-plugin 2.5.0                                           [jar]
[INFO] nacos-control-plugin 2.5.0                                         [jar]
[INFO] nacos-core 2.5.0                                                   [jar]
[INFO] nacos-encryption-plugin 2.5.0                                      [jar]
[INFO] nacos-config-plugin 2.5.0                                          [jar]
[INFO] nacos-config 2.5.0                                                 [jar]
[INFO] nacos-cmdb 2.5.0                                                   [jar]
[INFO] nacos-naming 2.5.0                                                 [jar]
[INFO] nacos-address 2.5.0                                                [jar]
[INFO] nacos-logger-adapter-impl 2.5.0                                    [pom]
[INFO] nacos-logback-adapter-12 2.5.0                                     [jar]
[INFO] nacos-log4j2-adapter 2.5.0                                         [jar]
[INFO] nacos-client 2.5.0                                                 [jar]
[INFO] nacos-plugin-default-impl 2.5.0                                    [pom]
[INFO] nacos-default-auth-plugin 2.5.0                                    [jar]
[INFO] nacos-default-control-plugin 2.5.0                                 [jar]
[INFO] nacos-default-plugin-all                                           [jar]
[INFO] nacos-istio 2.5.0                                                  [jar]
[INFO] nacos-prometheus 2.5.0                                             [jar]
[INFO] nacos-console 2.5.0                                                [jar]
[INFO] nacos-test 2.5.0                                                   [pom]
[INFO] nacos-config-test 2.5.0                                            [jar]
[INFO] nacos-naming-test 2.5.0                                            [jar]
[INFO] nacos-core-test 2.5.0                                              [jar]
[INFO] nacos-example 2.5.0                                                [jar]
[INFO] nacos-distribution 2.5.0                                           [pom]

......

龙芯大客户解决方案

如果大规模使用龙芯服务器执行 Maven 项目编译,上述方案并不成熟,因为速度慢,影响执行效率:存在两个仓库,并且龙芯仓库优先级高,除了极少数的 Maven 依赖使用一个 Maven 仓库(龙芯仓库)下载外,其他不在 龙芯 Maven 仓库中的依赖,依然会先访问 龙芯 Maven 仓库,再访问 Maven 中央仓库

龙芯官方 Maven 仓库的速度慢

虽然可以在一台机器上使用同一个 Maven 本地仓库,但是对于自动化 CI/CD 依赖变更时问题排查不利(非常细节的内容,不在意可不关注)

[INFO] --------------------< com.alibaba.nacos:nacos-all >---------------------
[INFO] Building Alibaba NACOS 2.5.0 2.5.0                                [1/37]
[INFO]   from pom.xml
[INFO] --------------------------------[ pom ]---------------------------------
Downloading from loongnix: https://maven.loongnix.cn/loongarch/maven/org/apache/maven/plugins/maven-enforcer-plugin/3.5.0/maven-enforcer-plugin-3.5.0.pom
Downloading from cloud-tencent: https://mirrors.cloud.tencent.com/nexus/repository/maven-public/org/apache/maven/plugins/maven-enforcer-plugin/3.5.0/maven-enforcer-plugin-3.5.0.pom
Downloaded from cloud-tencent: https://mirrors.cloud.tencent.com/nexus/repository/maven-public/org/apache/maven/plugins/maven-enforcer-plugin/3.5.0/maven-enforcer-plugin-3.5.0.pom (8.1 kB at 3.4 kB/s)
Downloading from loongnix: https://maven.loongnix.cn/loongarch/maven/org/apache/maven/enforcer/enforcer/3.5.0/enforcer-3.5.0.pom
Downloading from cloud-tencent: https://mirrors.cloud.tencent.com/nexus/repository/maven-public/org/apache/maven/enforcer/enforcer/3.5.0/enforcer-3.5.0.pom
Downloaded from cloud-tencent: https://mirrors.cloud.tencent.com/nexus/repository/maven-public/org/apache/maven/enforcer/enforcer/3.5.0/enforcer-3.5.0.pom (9.3 kB at 23 kB/s)
Downloading from loongnix: https://maven.loongnix.cn/loongarch/maven/org/apache/maven/maven-parent/42/maven-parent-42.pom
Downloading from cloud-tencent: https://mirrors.cloud.tencent.com/nexus/repository/maven-public/org/apache/maven/maven-parent/42/maven-parent-42.pom
Downloaded from cloud-tencent: https://mirrors.cloud.tencent.com/nexus/repository/maven-public/org/apache/maven/maven-parent/42/maven-parent-42.pom (50 kB at 191 kB/s)
Downloading from loongnix: https://maven.loongnix.cn/loongarch/maven/org/apache/apache/32/apache-32.pom
Downloading from cloud-tencent: https://mirrors.cloud.tencent.com/nexus/repository/maven-public/org/apache/apache/32/apache-32.pom
Downloaded from cloud-tencent: https://mirrors.cloud.tencent.com/nexus/repository/maven-public/org/apache/apache/32/apache-32.pom (24 kB at 63 kB/s)
Downloading from loongnix: https://maven.loongnix.cn/loongarch/maven/org/apache/maven/plugins/maven-enforcer-plugin/3.5.0/maven-enforcer-plugin-3.5.0.jar
Downloading from cloud-tencent: https://mirrors.cloud.tencent.com/nexus/repository/maven-public/org/apache/maven/plugins/maven-enforcer-plugin/3.5.0/maven-enforcer-plugin-3.5.0.jar
Downloaded from cloud-tencent: https://mirrors.cloud.tencent.com/nexus/repository/maven-public/org/apache/maven/plugins/maven-enforcer-plugin/3.5.0/maven-enforcer-plugin-3.5.0.jar (39 kB at 21 kB/s)

......

  1. 基于 Nexus 等软件,创建一个 Maven 中央仓库的代理仓库(可以直接使用 https://repo1.maven.org/maven2/ ,或者国内云厂商的地址,见:Maven 仓库地址
    • 国内云厂商 Maven 代理仓库 更新频率通常在 1 天左右,可能无法及时下载到最新版
    • 建议使用 https://repo1.maven.org/maven2/ 做一个候补
  2. 基于 Nexus 等软件,创建一个 龙芯官方 Maven 代理仓库
  3. 基于 Nexus 等软件,创建一个 Maven 合并仓库,合并仓库包含上述 Maven 代理仓库,并且将 龙芯官方 Maven 代理仓库左右第一优先级
  4. 首次下载某个依赖时,会通过 龙芯官方 Maven 代理仓库,访问龙芯官方 Maven 仓库,不存在时再访问 Maven 中央仓库的代理仓库,后续再下载同一依赖时,Maven 合并仓库直接返回 Maven 中央仓库的代理仓库已经缓存的依赖
  5. 可能遇见的问题:推荐在龙芯电脑上构建 Maven 项目时,使用 Maven 代理仓库:避免 龙芯 Maven 仓库无法下载等问题

可能存在没有完全适配的依赖或版本

Nacos 源码标签 2.5.0

git patch

使用方式:将 loong64.patch 放在 nacos 2.5.0 标签代码的上一级目录,执行 git apply ../loong64.patch 即可应用 git patch

作者测试时,https://maven.loongnix.cn/loongarch/maven/io/grpc/protoc-gen-grpc-java/ 只发布到了 1.54.2,但是项目原本需要 1.64.2,所以调整了一下依赖版本号

[root@anolis nacos]# git diff > ../loong64.patch
[root@anolis nacos]# cat ../loong64.patch 
diff --git a/consistency/pom.xml b/consistency/pom.xml
index d680880..4309e2f 100644
--- a/consistency/pom.xml
+++ b/consistency/pom.xml
@@ -38,7 +38,7 @@
                     <protocArtifact>com.google.protobuf:protoc:${protobuf-java.version}:exe:${os.detected.classifier}
                     </protocArtifact>
                     <pluginId>grpc-java</pluginId>
-                    <pluginArtifact>io.grpc:protoc-gen-grpc-java:${grpc-java.version}:exe:${os.detected.classifier}
+                    <pluginArtifact>io.grpc:protoc-gen-grpc-java:1.54.2:exe:${os.detected.classifier}
                     </pluginArtifact>
                 </configuration>
                 <executions>
diff --git a/pom.xml b/pom.xml
index 49bf51a..e6dea85 100644
--- a/pom.xml
+++ b/pom.xml
@@ -32,6 +32,36 @@
         <maven>3.2.5</maven>
     </prerequisites>
     
+     <pluginRepositories>
+        <pluginRepository>
+            <id>loongnix</id>
+            <name>Loongnix Maven Repository</name>
+            <url>https://maven.loongnix.cn/loongarch/maven/</url>
+            <releases>
+                <enabled>true</enabled>
+            </releases>
+           <snapshots>
+               <!-- 通常只需要 release 版本 -->
+                <enabled>false</enabled>
+            </snapshots>
+        </pluginRepository>
+    </pluginRepositories>
+   
+    <repositories>
+        <repository>
+            <id>loongarch</id>
+            <name>Loongnix Maven Repository</name>
+            <url>https://maven.loongnix.cn/loongarch/maven/</url>
+            <releases>
+                <enabled>true</enabled>
+            </releases>
+            <snapshots>
+                <!-- 通常只需要 release 版本 -->
+                <enabled>false</enabled>
+            </snapshots>
+        </repository>
+    </repositories>
+
     <scm>
         <url>git@github.com:alibaba/nacos.git</url>
         <connection>scm:git@github.com:alibaba/nacos.git</connection>
@@ -142,7 +172,7 @@
         <grpc-java.version>1.64.2</grpc-java.version>
         <proto-google-common-protos.version>2.17.0</proto-google-common-protos.version>
         <protobuf-java.version>3.25.5</protobuf-java.version>
-        <protoc-gen-grpc-java.version>${grpc-java.version}</protoc-gen-grpc-java.version>
+        <protoc-gen-grpc-java.version>1.54.2</protoc-gen-grpc-java.version>
         <hessian.version>4.0.63</hessian.version>
         <mockito.version>4.11.0</mockito.version>
         <HikariCP.version>3.4.2</HikariCP.version>
[root@anolis nacos]#