官术网_书友最值得收藏!

5.3.2 依賴編譯型語言的Java應用遷移

對于大型項目來說,很多時候不僅僅使用一種語言來開發應用,有時候會使用多種語言進行混合編程,例如著名的開源項目Netty,主體開發語言是Java,但是在部分項目里還使用了C語言。出現這種情況的一個原因是Netty在Linux下的異步/非阻塞網絡傳輸中,使用了Epoll——一個基于I/O事件通知的高性能多路復用機制。Netty是通過JNI方式提供Native Socket Transport的,在Netty的transport-native-epoll項目中,有相關調用的C代碼。

除此之外,在Netty的依賴項目netty-tcnative-parent中,也有JNI方式提供的C語言調用。

筆者負責的一款基于Java的物聯網平臺中也使用了Netty,在進行應用遷移時經過多次嘗試,解決了多個問題,最后遷移成功,這里通過Netty項目,演示一下依賴編譯型語言的Java應用的遷移。

1.遷移過程分析

Netty是開源的項目,在獲得所有的源代碼后,可以通過對代碼進行重新編譯的方式來執行遷移。因為代碼里有Java和C語言,并且Netty項目是通過Pom進行項目組織管理的,在遷移時不但要安裝C的編譯環境,還要安裝openjdk和Maven。

2.安裝依賴項

要安裝的依賴項較多,大部分可以通過yum安裝,命令如下:

     yum install gcc gcc-c++ make cmake3 libtool autoconf automake ant wget git openssl openssl -
     devel apr-devel ninja-build java-1.8.0-openjdk.aarch64 – y

安裝依賴項的時間有點長,根據系統中已安裝的軟件情況,可能需要幾分鐘到十幾分鐘,最后回顯如下:

因為后續步驟在編譯libressl-static模塊的時候需要cmake版本號大于3,并且需要ninja,這里提前做好軟連接,命令如下:

    ln -s /usr/bin/cmake3 /usr/bin/cmake
    ln -s /usr/bin/ninja-build /usr/bin/ninja

3.安裝Maven

Java應用的編譯打包需要Maven,安裝步驟如下:

步驟1:下載Maven 3.6.3安裝包,為了提高下載速度,可以使用國內的下載源,命令如下:

    wget https://mirrors.tuna.tsinghua.edu.cn/apache/maven/maven - 3/3.6.3/binaries/apache -
    maven-3.6.3 -bin.tar.gz

步驟2:解壓Maven安裝包,命令如下:

    tar -zvxf apache-maven-3.6.3 -bin.tar.gz

步驟3:移動Maven到指定目錄,命令如下:

    mv apache-maven-3.6.3 /opt/tools/

步驟4:配置環境變量,修改/etc/profile文件,在文件最后增加Maven的環境信息,增加的內容如下:

    MAVEN_HOME=/opt/tools/apache-maven-3.6.3
    PATH= $ MAVEN_HOME/bin:$ JAVA_HOME/bin: $ PATH
    export MAVEN_HOME JAVA_HOME PATH

步驟5:使環境變量生效,命令如下:

    source /etc/profile

步驟6:由于Maven中央倉庫的下載速度受限,所以這里配置Maven的鏡像倉庫網址為國內的鏡像,要修改的配置文件路徑為/opt/tools/apache-maven-3.6.3/conf/settings.xml,在該文件的<mirrors>節中添加新的鏡像,添加的內容如下:

步驟7:查看Maven是否安裝成功,命令及回顯如下:

如果出現類似上面的回顯,表示Maven安裝配置成功了。

4.處理鯤鵬架構中char類型為無符號型的默認設置

直接對代碼中char類型進行更改風險較高,工作量也很大,這里通過設置gcc和g++的編譯選項來處理,也就是把這兩個編譯器的編譯加上-fsigned-char的選項。

1)修改gcc編譯選項

步驟1:確認gcc的位置,命令及回顯如下:

    [root@ecs-kunpeng ~]#command -v gcc
    /usr/bin/gcc

根據系統不同,位置可能有差異,筆者本機的位置在/usr/bin/gcc。

步驟2:修改gcc的名字為gcc-ori,命令如下:

    mv/usr/bin/gcc /usr/bin/gcc-ori

步驟3:創建/usr/bin/gcc文件,命令如下:

    vi /usr/bin/gcc

步驟4:編輯/bin/gcc文件,輸入內容如下:

    #! /bin/sh
    /usr/bin/gcc-ori -fsigned-char "$@"

步驟5:給/bin/gcc添加執行權限,命令如下:

    chmod +x /usr/bin/gcc

步驟6:查看gcc是否可以成功執行,命令及回顯如下:

    [root@ecs-kunpeng ~]#gcc --version
    gcc-ori (GCC) 4.8.5 20150623 (Red Hat 4.8.5-44)
    Copyright (C) 2015 Free Software Foundation, Inc.
    This is free software; see the source for copying conditions. There is NO
    warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

如果看到類似上面的回顯,表示gcc修改成功了。

2)修改g++編譯選項

步驟1:確認g++的位置,命令及回顯如下:

    [root@ecs-kunpeng ~]#command -v g++
    /usr/bin/g++

本機位置是/usr/bin/g++,不同的服務器位置可能不同。

步驟2:修改g++的名字為g++-ori,命令如下:

    mv /usr/bin/g++ /usr/bin/g++ -ori

步驟3:創建/usr/bin/g++文件,命令如下:

    vi /usr/bin/g++

步驟4:編輯/bin/g++文件,輸入內容如下:

    #! /bin/sh
    /usr/bin/g++ -ori -fsigned-char "$@"

步驟5:給/bin/g++添加執行權限,命令如下:

    chmod +x /usr/bin/g++

步驟6:查看g++是否可以成功執行,命令及回顯如下:

    [root@ecs-kunpeng ~]#g++ --version
    g++ -ori (GCC) 4.8.5 20150623 (Red Hat 4.8.5-44)
    Copyright (C) 2015 Free Software Foundation, Inc.
    This is free software; see the source for copying conditions. There is NO
    warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

如果看到類似上面的回顯,表示g++修改成功了。

5.加速編譯準備

在正式編譯以前,需要先下載3個安裝包。后面的編譯過程需要從多個網站下載安裝包,這些網站的服務器一般都在境外,下載速度較慢,可能會因為下載不成功導致編譯失敗。

步驟1:下載apr-1.6.5,進入/data/soft/文件夾,下載命令如下:

    wget https://mirrors.tuna.tsinghua.edu.cn/apache/apr/apr-1.6.5.tar.gz

步驟2:下載libressl-3.1.1,下載命令如下:

    wget https://mirrors.tuna.tsinghua.edu.cn/OpenBSD/LibreSSL/libressl-3.1.1.tar.gz

步驟3:下載openssl-1.1.1g,下載命令如下:

    wget https://www.openssl.org/source/openssl-1.1.1g.tar.gz

6.編譯netty-tcnative-2.0.34

步驟1:進入/data/soft/下載netty-tcnative源碼包,下載命令如下:

    wget https://GitHub.com/netty/netty - tcnative/archive/netty - tcnative - parent - 2.0.34.
    Final.tar.gz

步驟2:解壓源碼包,并進入解壓后目錄,命令如下:

    tar -zxvf netty-tcnative-parent-2.0.34.Final.tar.gz
    cd netty-tcnative-netty-tcnative-parent-2.0.34.Final/

步驟3:修改pom文件,注釋掉對apr的下載,對于2.0.34版本來說,注釋行在第474行,修改后的該段配置如下:

注釋掉該行后,mvn編譯時將不再從這里下載。

步驟4:進入libressl-static目錄,修改pom文件,注釋掉對libssl的下載,注釋行在第263行,修改后的該段配置如下:

步驟5:進入openssl-static目錄,修改pom文件,注釋掉對openssl的下載,注釋行在第334行和第338行,修改后的該段配置如下:

步驟6:注釋掉對boringssl-static的編譯(在第603行),因為boringssl-static需要從谷歌服務器獲取資源,由于無法獲取成功,這里就取消對它的編譯,但不影響后續的使用(如果確實要用,可以把獲取源碼網址改為GitHub上的源碼網址,這里就不演示了)。編輯源代碼主目錄的pom文件,修改后的該段配置如下:

步驟7:提前創建好openssl-static和libressl-static項目的target目錄,命令如下:

     mkdir /data/soft/netty- tcnative-netty- tcnative-parent- 2.0.34.Final/openssl - static/
     target/
     mkdir /data/soft/netty- tcnative-netty- tcnative-parent- 2.0.34.Final/libressl - static/
     target/

步驟8:復制預先下載的文件到target目錄,命令如下:

     cp /data/soft/apr-1.6.5.tar.gz /data/soft/netty-tcnative-netty-tcnative-parent-2.0.
     34.Final/openssl-static/target/
     cp /data/soft/openssl-1.1.1g.tar.gz /data/soft/netty-tcnative-netty-tcnative-parent-
     2.0.34.Final/openssl-static/target/
     cp /data/soft/apr-1.6.5.tar.gz /data/soft/netty-tcnative-netty-tcnative-parent-2.0.
     34.Final/libressl-static/target/
     cp /data/soft/libressl-3.1.1.tar.gz /data/soft/netty-tcnative-netty-tcnative-parent-
     2.0.34.Final/libressl-static/target/

步驟9:進入主目錄,執行編譯,命令如下:

     cd /data/soft/netty-tcnative-netty-tcnative-parent-2.0.34.Final/
     mvn install

最后編譯成功的回顯如下:

7.編譯netty-all-4.1.52

步驟1:進入/data/soft/下載netty-all源碼包,下載命令如下:

     wget https://GitHub.com/netty/netty/archive/netty-4.1.52.Final.tar.gz

步驟2:解壓源碼包,并進入解壓后目錄,命令如下:

     tar -zxvf netty-4.1.52.Final.tar.gz
     cd netty-netty-4.1.52.Final/

步驟3:處理jni.h問題。在后續的編譯中,可能會出現找不到jni.h和jni_md.h的錯誤,如圖5-9所示。

圖5-9 編譯錯誤

出現這種錯誤的原因是C編譯器找不到頭文件的位置,所以需要直接告訴編譯器頭文件在哪里,就是通過C編譯器選項CFLAGS傳過去頭文件的路徑。本機的jni.h文件在/usr/lib/jvm/java/include目錄下,jni_md.h文件在/usr/lib/jvm/java/include/Linux/目錄下。編輯transport-native-UNIX-common下的pom文件,命令如下:

     vim /data/soft/netty-netty-4.1.52.Final/transport-native-UNIX-common/pom.xml

要修改的CFLAGS選項在第198行和第263行,在值的后面加上頭文件的位置,代碼如下:

     -I/usr/lib/jvm/java/include -I/usr/lib/jvm/java/include/Linux/

修改后的效果如下所示,注意修改后的字符串也是全部在value值的引號里面,代碼如下:

步驟4:編譯netty-all,進入源碼主目錄,執行編譯,命令如下:

     mvn install -DskipTests

該命令將跳過測試過程,經過十幾分鐘的編譯后,可以看到成功編譯的回顯如下所示:

鯤鵬架構的jar包就在各個項目的target目錄下,例如transport-native-epoll項目下的jar包,顯示如下:

包含aarch_64的jar包就是鯤鵬架構下適用的jar包。

主站蜘蛛池模板: 石棉县| 呼伦贝尔市| 虹口区| 廉江市| 万全县| 靖安县| 上蔡县| 资溪县| 当涂县| 内黄县| 周口市| 南皮县| 福州市| 广昌县| 禹州市| 石林| 潜山县| 永吉县| 定远县| 肇东市| 喀喇沁旗| 荥阳市| 彰化市| 南投县| 菏泽市| 郴州市| 丹凤县| 河津市| 高邮市| 闽清县| 仁怀市| 双辽市| 防城港市| 临沭县| 荃湾区| 保定市| 廊坊市| 甘德县| 环江| 恩平市| 磐石市|