Java 程序编译
编译流程
C 语言源码编译过程,对于单文件,我们可以使用 gcc 命令直接编译即可,但如果是大型商业项目,源码文件多,存在各种依赖,各种配置路径,各种库的支持等,几乎无法手动编译,所以 我们通常会借助 make 命令的编译工具链来完成大型项目的编译,在使用 Java 语言开发的项目中,也是同样如此
针对单个的 java 源码文件,我们可以直接使用 javac 命令进行编译,但是大型商业项目,也同样需要使 用专门的编译工具进行编译
-
获取 Java 程序源码
-
进入源码目录,运行 mvn 命令,mvn 会根据项目中的 pom.xml 文件和编译参数编译源码,得到 .war 或 .jar 结尾的目标文件
-
部署运行
使用 Maven 编译 Java 项目
Maven 介绍
Java 中主要有三大构建工具:Ant、Maven 和 Gradle,经过多年的发展,Ant 几乎销声匿迹, 当前 Maven 占主流地位
Maven 翻译为 "专家,内行",诞生于2004年7月, 是 Apache 基金会旗下的一个纯 Java 开发的开源项目
Maven 是一个项目管理工具,可以对 Java 项目进行构建、解决打包依赖等
它为开发者提供了一套完整的构建生命周期框架,开发团队很容易地就能够自动完成工程的基础构建配 置,在有多个开发团队环境的情况下,Maven 能够在很短的时间内使得每项工作都按照标准进行,那是 因为大部分的工程配置操作都非常简单并且可复用
Maven基干项目对象模型(POM project object model)实现项目管理,POM即一段描述信息(配置)可以 用来管理项目的构建,因此每个maven项目都有一个pom.xml文件
POM( Project Object Model,项目对象模型 ) 是 Maven 工程的基本工作单元,是一个 XML 文件,包含 了项目的基本信息,用于描述项目如何构建,声明项目依赖等,在执行任务或目标时,Maven 会在当前目录中查找 pom 文件,通过读取 pom 文件获取所需的配置信息,然后执行目标。本质上,每个Maven 项目都包含一个POM文件,该文件定义每个项目的对应的相关信息,Maven使用POM来决定不同的构 建动作,及制品的生成等
pom.xml 文件中可以指定以下配置:
bash
项目依赖
插件
执行目标
项目构建 profile
项目版本
项目开发者列表 相关邮件列表信息
用<packaging> 指定项目打包形式,jar或者war
Maven的仓库分类
中央仓库(Central Repository):
Maven官方服务器里面存放了绝大多数市面上流行的 jar 包,允许用户注册后,上传自己的项目到官方仓库服务器
镜像仓库(Mirror Repository):
对于国内来说访问国外的中央Maven仓库会特别慢
镜像仓库就是中央仓库的备份/镜像
国内开发者多使用阿里云镜像或华为云镜像,这样可以大大提升从中央仓库下载资源的速度
但它仍然是一个远程库
本地仓库(Local Repository):
使用当前执行maven构建的本机的仓库文件夹作为本地仓库
本地仓库指本机的一份拷贝,用来缓存从远程仓库下载的包
也包含尚未发布的临时构件
Maven 仓库使用流程
-
首先,在本地repo搜索指定的依赖,而后是Maven的repo服务
-
若配置了远程repo服务,Maven还是搜索该repo
-
Maven默认使用的是其官方存储库,在国内的下载速度较慢,因而建议使用国内的Maven镜像仓 库,例如阿里的镜像仓库等
通常编译打包JAVA项目会依赖很多的资源即包jar文件才能完成,所以需要通过Maven的资源坐标路径查 找到相关包并下载使用
Local Repository 本地仓库说明
-
Maven 的本地仓库存储了 maven 需要的插件和你项目中需要用到的依赖 jar 包,当 maven 使用 到上述内容的时候,如果本地仓库中已经存在了,则直接使用本地仓库中内容,如果本地仓库中不 存在,则需要从中央仓库下载到本地然后才可以继续使用,因此 maven 的本地仓库会存储很多的 文件
-
Maven的默认配置的本地仓库路径 : ${HOME}/.m2/repository
-
可以在maven的配置文件 settings.xml 文中指定本地仓库路径
Maven 的资源坐标
-
Groupld:组织ID,一般是反写的公司域名com.example ,同一个公司的Groupld都是相同的
-
Artifactld:制器ID,一般是项目名,如myapp,也是生成包jar/war的名
-
Version:版本,比如:1.2.3
maven 下载
bash
https://maven.apache.org/download.cgi #官方
http://mirrors.tuna.tsinghua.edu.cn/apache/maven #清华镜像源
https://archive.apache.org/dist/maven/maven-3 #官方各版本下载地址,推荐使用次新版本
安装maven前必须安装java 环境
-
Maven 3.3 要求 JDK 1.7 或以上
-
Maven 3.2 要求 JDK 1.6 或以上
-
Maven 3.0/3.1 要求 JDK 1.5 或以上
注意: Maven 所安装 JDK 的版本不影响编译应用的所依赖的 JDK 版本,比如 Maven 安装 JDK11,而 java 应用 Jpress 可以使用 JDK8
Maven 安装和配置
bash
#apt 安装,如果没有安装 JDK,会自动安装
[root@ubuntu24 ~]# apt list maven
Listing... Done
maven/noble 3.8.7-2 all
[root@ubuntu24 ~]# apt install maven -y
[root@ubuntu24 ~]# which mvn
/usr/bin/mvn
[root@ubuntu24 ~]# mvn --version
Apache Maven 3.8.7
Maven home: /usr/share/maven
Java version: 11.0.24, vendor: Ubuntu, runtime: /usr/lib/jvm/java-11-openjdk-amd64
Default locale: en_US, platform encoding: UTF-8
OS name: "linux", version: "6.8.0-45-generic", arch: "amd64", family: "unix"
#修改默认仓库为国内源,在 mirrors 标签内添加阿里源配置
[root@ubuntu24 ~]# vim /etc/maven/settings.xml
<mirror>
<id>aliyunmaven</id>
<mirrorOf>*</mirrorOf>
<name>阿里云公共仓库</name>
<url>https://maven.aliyun.com/repository/public</url>
</mirror>
二进制安装
bash
[root@ubuntu24 ~]# wget https://mirrors.tuna.tsinghua.edu.cn/apache/maven/maven3/3.9.6/binaries/apache-maven-3.9.6-bin.zip
[root@ubuntu24 ~]# unzip apache-maven-3.9.6-bin.zip -d /usr/local/
[root@ubuntu24 ~]# ln -s /usr/local/apache-maven-3.9.6/ /usr/local/maven
[root@ubuntu24 ~]# ls /usr/local/maven
bin boot conf lib LICENSE NOTICE README.txt
[root@ubuntu24 ~]# ls /usr/local/maven/bin/
m2.conf mvn mvn.cmd mvnDebug mvnDebug.cmd mvnyjp
[root@ubuntu24 ~]# /usr/local/maven/bin/mvn --version
Apache Maven 3.9.6 (bc0240f3c744dd6b6ec2920b3cd08dcc295161ae)
Maven home: /usr/local/maven
Java version: 11.0.22, vendor: Oracle Corporation, runtime: /usr/lib/jvm/jdk-11-
oracle-x64
Default locale: en_US, platform encoding: UTF-8
OS name: "linux", version: "5.15.0-102-generic", arch: "amd64", family: "unix"
[root@ubuntu ~]#cat /usr/local/maven/bin/mvn
......
......
exec "$JAVACMD" \
$MAVEN_OPTS \
$MAVEN_DEBUG_OPTS \
-classpath "${CLASSWORLDS_JAR}" \
"-Dclassworlds.conf=${MAVEN_HOME}/bin/m2.conf" \
"-Dmaven.home=${MAVEN_HOME}" \
"-Dlibrary.jansi.path=${MAVEN_HOME}/lib/jansi-native" \
"-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \
${CLASSWORLDS_LAUNCHER} ${MAVEN_ARGS} "$@"
#加PATH
[root@ubuntu ~]# ln -s /usr/local/maven/bin/mvn /usr/local/bin/
#修改默认仓库为国内源,在 mirrors 标签内添加阿里源配置
[root@ubuntu ~]# vim /usr/local/maven/conf/settings.xml
<mirror>
<id>aliyunmaven</id>
<mirrorOf>*</mirrorOf>
<name>阿里云公共仓库</name>
<url>https://maven.aliyun.com/repository/public</url>
</mirror>
</mirrors>
主要配置文件
-
在 maven 中主要的配置文件有三个,分别是全局的 settings.xml ,用户的 settings.xml,和每个 项目单独的配置文件 pom.xml
-
全局 settings.xml 是 maven 的全局配置文件,一般位于 ${maven.home}/conf/settings.xml,即 maven 文件夹下的 conf 中
-
用户 setting 是 maven 的用户配置文件,一般位于 ${user.home}/.m2/settings.xml,即每位用户 都有一份配置文件
-
pom.xml 文件是项目配置文件,一般位于项目根目录下或子目录下
-
配置优先级从高到低:pom.xml > 本地 settings > 全局 settings
-
如果这些文件同时存在,在应用配置时,会合并它们的内容,如果有重复的配置,优先级高的配置 会覆盖优先级低的。
settings.xml 用来配置 maven 项目中的各种参数文件,包括本地仓库、远程仓库、私服、认证等信息
bash
/etc/maven/settings.xml #包安装
/usr/local/maven/conf/settings.xml #源码安装
#主要配置项
<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
https://maven.apache.org/xsd/settings-1.0.0.xsd">
<localRepository>
<interactiveMode>
<usePluginRegistry>
<offline>
<pluginGroups>
<servers>
<mirrors>
<proxies>
<profiles>
<activeProfiles>
</settings>
#localRepository 配置本地仓库目录,默认${user.home}/.m2/repository
<!-- localRepository
| The path to the local repository maven will use to store artifacts.
|
| Default: ${user.home}/.m2/repository
<localRepository>/path/to/local/repo</localRepository>
-->
#interactiveMode 是否需要和用户交换获得输入,默认 true
<!-- interactiveMode
| This will determine whether maven prompts you when it needs input. If setto false,
| maven will use a sensible default value, perhaps based on some other setting, for
| the parameter in question.
|
| Default: true
<interactiveMode>true</interactiveMode>
-->
#offline 是否可以在没有网络的情况下进行编译,默认 false
<!-- offline
| Determines whether maven should attempt to connect to the network when executing a build.
| This will have an effect on artifact downloads, artifact deployment, and others.
|
| Default: false
<offline>false</offline>
-->
#proxies 用来配置代理
<proxies>
<!-- proxy
| Specification for one proxy, to be used in connecting to the network.
|
<proxy>
<id>optional</id>
<active>true</active>
<protocol>http</protocol>
<username>proxyuser</username>
<password>proxypass</password>
<host>proxy.host.net</host>
<port>80</port>
<nonProxyHosts>local.net|some.host.com</nonProxyHosts>
</proxy>
-->
</proxies>
# server 配置私有仓库地址,包括用户名,密码等
<servers>
<!-- server
| Specifies the authentication information to use when connecting to a particular server, identified by
| a unique name within the system (referred to by the 'id' attribute below).
|
| NOTE: You should either specify username/password OR privateKey/passphrase, since these pairings are
| used together.
|
<server>
<id>deploymentRepo</id>
<username>repouser</username>
<password>repopwd</password>
</server>
-->
<!-- Another sample, using keys to authenticate.
<server>
<id>siteServer</id>
<privateKey>/path/to/private/key</privateKey>
<passphrase>optional; leave empty if not used.</passphrase>
</server>
-->
</servers>
# mirror 配置依赖仓库地址,可以有多个仓库配置
<mirrors>
<!-- mirror
| Specifies a repository mirror site to use instead of a given repository. The repository that
| this mirror serves has an ID that matches the mirrorOf element of this mirror. IDs are used
| for inheritance and direct lookup purposes, and must be unique across the set of mirrors.
|
<mirror>
<id>mirrorId</id>
<mirrorOf>repositoryId</mirrorOf>
<name>Human Readable Name for this Mirror.</name>
<url>http://my.repository.com/repo/path</url>
</mirror>
-->
<mirror>
<id>maven-default-http-blocker</id>
<mirrorOf>external:http:*</mirrorOf>
<name>Pseudo repository to mirror external repositories initially using HTTP.</name>
<url>http://0.0.0.0/</url>
<blocked>true</blocked>
</mirror>
</mirrors>
#profile 用来配置构建参数,例如 jdk 版本等,也可以在项目的 pom 文件中配置
<profiles>
<!-- profile
| Specifies a set of introductions to the build process, to be activated using one or more of the
| mechanisms described above. For inheritance purposes, and to activate profiles via <activatedProfiles/>
| or the command line, profiles have to have an ID that is unique.
|
| An encouraged best practice for profile identification is to use a consistent naming convention
| for profiles, such as 'env-dev', 'env-test', 'env-production', 'userjdcasey', 'user-brett', etc.
| This will make it more intuitive to understand what the set of introduced profiles is attempting
| to accomplish, particularly when you only have a list of profile id's for debug.
|
| This profile example uses the JDK version to trigger activation, and provides a JDK-specific repo.
<profile>
<id>jdk-1.4</id>
<activation>
<jdk>1.4</jdk>
</activation>
<repositories>
<repository>
<id>jdk14</id>
<name>Repository for JDK 1.4 builds</name>
<url>http://www.myhost.com/maven/jdk14</url>
<layout>default</layout>
<snapshotPolicy>always</snapshotPolicy>
</repository>
</repositories>
</profile>
-->
<!--
| Here is another profile, activated by the property 'target-env' with a value of 'dev', which
| provides a specific path to the Tomcat instance. To use this, your plugin configuration might
| hypothetically look like:
|
| ...
| <plugin>
| <groupId>org.myco.myplugins</groupId>
| <artifactId>myplugin</artifactId>
|
| <configuration>
| <tomcatLocation>${tomcatPath}</tomcatLocation>
| </configuration>
| </plugin>
| ...
|
| NOTE: If you just wanted to inject this configuration whenever someone set 'target-env' to
| anything, you could just leave off the <value/> inside the activation-property.
|
<profile>
<id>env-dev</id>
<activation>
<property>
<name>target-env</name>
<value>dev</value>
</property>
</activation>
<properties>
<tomcatPath>/path/to/tomcat/instance</tomcatPath>
</properties>
</profile>
-->
</profiles>
Maven 命令和编译流程
mvn 命令选项
bash
mvn [options] [<goal(s)>] [<phase(s)>]
#常用选项
-am|--also-make #构建指定模块,同时构建指定模块的依赖模块
-amd|--also-make-dependents #构建指定模块,同时构建依赖于指定模块的其它模块
-B|--batch-mode #批处理模式编译
-C|--strict-checksums #检查不通过,则构建失败(严格模式)
-c|--lax-checksums #检查不通过,则输出告警信息(宽松模式)
--color <arg> #定义输出内容的颜色属性 auto|always|never
-D|--define <arg> #定义系统属性
-e|--errors #输出执行错误信息
-emp|--encrypt-master-password <arg> #加密主安全密码,存储到Maven settings文件里
-ep|--encrypt-password <arg> #加密服务器密码,存储到Maven settings文件里
-f|--file <arg> #指定项目的pom.xml 文件
-fae|--fail-at-end #如果编译出错,不停下来,继续执行
-ff|--fail-fast #构建失败直接退出
-fn|--fail-never #无论编译结果如何,都认为编译成功
-gs|--global-settings <arg> #指定 setting.xml
-gt|--global-toolchains <arg> #指定全局工具链文件路径
-h|--help #显示帮助信息
-l|--log-file <arg> #将编译过程的输出保存到指定文件
-N|--non-recursive #不递归构建子项目
-npr|--no-plugin-registry #对插件版本不使用~/.m2/pluginregistry.xml(插件注册表)里的配置
-o|--offline #不依赖网络更新
-P|--activate-profiles <arg> #激活指定的配置文件
-pl|--projects <arg> #仅在指定模块上执行编译
-q|--quiet #安静模式,不显示编译过程,只显示编译错误
-rf|--resume-from <arg> #从指定的项目(模块)开始继续编译
-s|--settings <arg> #指定 setting.xml
-t|--toolchains <arg> #指定用户工具链文件路径
-T|--threads <arg> #指定编译线程数,可以是整数或者小数,例如 1.5C 表示1.5倍的核心数乘积
-U|--update-snapshots #强制检查远程仓库中是否存在更新的依赖包版本
-v|--version #显示版本信息
-V|--show-version #先输出版本信息,再编译
-X|--debug #调试模式
mvn 二级命令
bash
[root@ubuntu24 ~]# mvn
[INFO] Scanning for projects...
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 0.077 s
[INFO] Finished at: 2024-09-24T02:20:41Z
[INFO] ------------------------------------------------------------------------
[ERROR] No goals have been specified for this build. You must specify a valid lifecycle phase or a goal in the format <plugin-prefix>:<goal> or <plugin-group-id>:<plugin-artifact-id>[:<plugin-version>]:<goal>. Available lifecycle phases are: validate, initialize, generate-sources, process-sources, generate-resources, process-resources, compile, process-classes, generate-test-sources, process-test-sources, generate-test-resources, process-test-resources, test-compile, process-test-classes, test, prepare-package, package, pre-integration-test, integration-test, post-integration-test, verify, install, deploy, pre-clean, clean, post-clean, pre-site, site, post-site, site-deploy. -> [Help 1]
[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/NoGoalSpecifiedException
常用构建子命令
命令 | 说明 |
---|---|
clean | 清理之前己构建和编译的产物 |
compile | 将源码编译成class字节码文件 |
test | 行项目的单元测试 |
package | 将项目打包成 war 包 或 jar 包 |
install | 将项目打包并安装到本地 Maven 仓库,以便其他项目可以使用 |
deploy | 将项目发布到远程仓库,通常是用于发布到公司或公共 Maven 仓库 |
dependency:resolve | 解析并下载项目依赖 |
dependency:tree | 显示项目依赖树 |
clean install | 先清理,再编译安装 |
bash
mvn clean install package #清理,打包,并安装
mvn clean install package -Dmaven.test.skip=true #清理,打包,并安装,跳过单元测试部份
mvn -T 4 clean install package -Dmaven.test.skip=true #4线程编译
mvn -T 2C clean install package -Dmaven.test.skip=true #2倍CPU核心线程数编译
mvn clean install package -Dmaven.test.skip=true -Dmaven.compile.fork=true #多线程编译
mvn -f mall-gateway clean package dockerfile:build #构建docker镜像,要在pom.xml中配置
bash
#安装git,git 用来clone 代码
[root@ubuntu24 ~]# apt install git -y
#clone 代码到本地
[root@ubuntu ~]# git clone https://gitee.com/lbtooth/spring-boot-helloworld.git
[root@ubuntu24 ~]# ls spring-boot-helloworld/
deploy Dockerfile Dockerfile-multistages Jenkinsfile LICENSE pom.xml README.md sonar-project.properties src
#源码目录
[root@ubuntu24 ~]# ls spring-boot-helloworld/src/
main test
[root@ubuntu24 ~]# cat spring-boot-helloworld/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/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.neo</groupId>
<artifactId>spring-boot-helloworld</artifactId>
<version>0.3-SNAPSHOT</version> #编译后的版本是0.3.0
<packaging>jar</packaging> #编译后的包提 jar 包
<name>spring-boot-helloworld</name> #项目名
<description>Demo project for Spring Boot</description> #项目描述
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.3.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties> #当前项目支持的JAVA 版本
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies> #项目依赖列表
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<fork>true</fork>
</configuration>
</plugin>
</plugins>
</build>
#为当前项目配置加速,也可以写
在全局的 settings.xml中
<!-- 配置阿里云仓库 -->
<repositories>
<repository>
<id>aliyun-repos</id>
<url>https://maven.aliyun.com/repository/public</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>aliyun-repos</id>
<url>https://maven.aliyun.com/repository/public</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
</pluginRepository>
</pluginRepositories>
</project>
#开始编译,清理旧的编译内容,重新构建,并跳过测试
[root@ubuntu24 spring-boot-helloworld]# mvn clean package -Dmaven.test.skip=true
#多出一个target 目录
[root@ubuntu24 spring-boot-helloworld]# ls
deploy Dockerfile Dockerfile-multistages Jenkinsfile LICENSE pom.xml README.md sonar-project.properties src target
#spring-boot-helloworld-0.9.0-SNAPSHOT.jar 就是构建好的目标
[root@ubuntu24 spring-boot-helloworld]# ls target/
classes generated-sources maven-archiver maven-status spring-boot-helloworld-0.3-SNAPSHOT.jar spring-boot-helloworld-0.3-SNAPSHOT.jar.original
#依赖包都下载到本地了
[root@ubuntu24 ~]# ls .m2
repository
[root@ubuntu24 ~]# du -sh .m2
52M .m2
#运行,根据输出内容,可知PID为3182,占用了 8080端口,如果需要修改端口,可加 --server.port=修改的端口号
[root@ubuntu24 target]# java -jar /root/spring-boot-helloworld/target/spring-boot-helloworld-0.3-SNAPSHOT.jar
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.1.3.RELEASE)
2024-09-24 02:41:47.163 INFO 3182 --- [ main] com.neo.Application : Starting Application v0.3-SNAPSHOT on ubuntu24 with PID 3182 (/root/spring-boot-helloworld/target/spring-boot-helloworld-0.3-SNAPSHOT.jar started by root in /root/spring-boot-helloworld/target)
2024-09-24 02:41:47.165 INFO 3182 --- [ main] com.neo.Application : No active profile set, falling back to default profiles: default
2024-09-24 02:41:48.198 INFO 3182 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8080 (http)
2024-09-24 02:41:48.228 INFO 3182 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
...
[root@ubuntu24 spring-boot-helloworld]# mvn clean
[INFO] Scanning for projects...
[INFO]
[INFO] -------------------< com.neo:spring-boot-helloworld >-------------------
[INFO] Building spring-boot-helloworld 0.3-SNAPSHOT
[INFO] --------------------------------[ jar ]---------------------------------
[INFO]
[INFO] --- maven-clean-plugin:3.1.0:clean (default-clean) @ spring-boot-helloworld ---
[INFO] Deleting /root/spring-boot-helloworld/target
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 0.344 s
[INFO] Finished at: 2024-09-24T02:46:29Z
[INFO] ------------------------------------------------------------------------
#清理,会删除己构建的内容
[root@ubuntu24 spring-boot-helloworld]# ls
deploy Dockerfile Dockerfile-multistages Jenkinsfile LICENSE pom.xml README.md sonar-project.properties src
#执行单元测试
[root@ubuntu24 spring-boot-helloworld]# mvn test
...
...
[INFO]
[INFO] Results:
[INFO]
[INFO] Tests run: 3, Failures: 0, Errors: 0, Skipped: 0
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 6.798 s
[INFO] Finished at: 2024-09-24T02:47:39Z
[INFO] -----------------------------------------------------------------------
使用 Nexus 构建私有仓库
Nexus 介绍
Nexus 是一个非常流行的开源软件项目,主要用于软件包管理和存储,它最初是由 Sonatype 开发的, 旨在帮助开发人员和组织管理他们的软件构建、依赖关系和存储库,Nexus 主要有两个版本:Nexus Repository Manager 和 Nexus Firewall
Nexus Repository Manager
Nexus Repository Manager 是一个用于管理软件构建和依赖关系的存储库管理器。它支持多种包类 型,包括 Maven、npm、Docker、RubyGems、PyPI 等。以下是 Nexus Repository Manager 的主要功能和用途:
-
包管理:开发人员可以使用 Nexus Repository Manager 来存储、管理和共享各种软件包和构建组件;
-
代理远程存储库:Nexus 可以代理远程存储库,使您能够在本地缓存外部依赖项,提高构建速度和 稳定性;
-
安全和权限:Nexus 具有丰富的安全功能,可以管理用户访问权限,设置安全策略,保护组织的代 码库免受潜在的安全漏洞;
-
镜像和同步:Nexus 支持镜像和同步功能,让您能够创建多个存储库实例,并确保它们之间的数据同步;
Nexus 安装和配置 Maven 仓库
IP | 部署服务 | 备注 |
---|---|---|
java,Maven | 将 Maven 中的仓库配置指向自建的私有仓库 | |
Nexus Server | 内存需要 4G 以上,实现 Maven 的仓库,apt 仓库,yum 仓库 |
安装 Nexus,并配置 Maven 仓库
bash
[root@ubuntu24 ~]# apt install openjdk-11-jdk
[root@ubuntu24 ~]# wget https://download.sonatype.com/nexus/3/nexus-3.67.1-01-java11-unix.tar.gz
#解压缩到/usr/local/
[root@ubuntu24 ~]# tar xf nexus-3.67.1-01-java11-unix.tar.gz -C /usr/local/
#创建软连接
[root@ubuntu24 local]# ln -sv /usr/local/nexus-3.67.1-01/ /usr/local/nexus
'/usr/local/nexus' -> '/usr/local/nexus-3.67.1-01/'
[root@ubuntu24 local]# ls nexus
bin deploy etc lib NOTICE.txt OSS-LICENSE.txt PRO-LICENSE.txt public replicator system
#主配置文件,指定监听的端口号和IP
[root@ubuntu24 local]# cat nexus/etc/nexus-default.properties
## DO NOT EDIT - CUSTOMIZATIONS BELONG IN $data-dir/etc/nexus.properties
##
# Jetty section
application-port=8081
application-host=0.0.0.0
nexus-args=${jetty.etc}/jetty.xml,${jetty.etc}/jetty-http.xml,${jetty.etc}/jetty-requestlog.xml
nexus-context-path=/
# Nexus section
nexus-edition=nexus-pro-edition
nexus-features=\
nexus-pro-feature
nexus.hazelcast.discovery.isEnabled=true
[root@ubuntu24 local]# tree /usr/local/nexus/bin/
/usr/local/nexus/bin/
├── contrib
│ ├── karaf-service.sh
│ ├── karaf-service-template.conf
│ ├── karaf-service-template.init
│ ├── karaf-service-template.init-debian
│ ├── karaf-service-template.init-redhat
│ ├── karaf-service-template.solaris-smf
│ ├── karaf-service-template.systemd
│ ├── karaf-service-template.systemd-instances
│ ├── karaf-service-win.exe
│ └── karaf-service-win.xml
├── nexus #可执行二进制脚本文件,主程序
├── nexus.rc #配置运行时用户身份
└── nexus.vmoptions #配置服务启动时的 JAVA 选项
2 directories, 13 files
#指定运行身份
[root@ubuntu24 local]# cat /usr/local/nexus/bin/nexus.rc
run_as_user="root"
[root@ubuntu24 local]# ln -sv /usr/local/nexus/bin/nexus /usr/bin/
'/usr/bin/nexus' -> '/usr/local/nexus/bin/nexus'
[root@ubuntu24 local]# nexus
WARNING: ************************************************************
WARNING: Detected execution as "root" user. This is NOT recommended!
WARNING: ************************************************************
Usage: /usr/bin/nexus {start|stop|run|run-redirect|status|restart|force-reload}
[root@ubuntu24 local]# nexus start
WARNING: ************************************************************
WARNING: Detected execution as "root" user. This is NOT recommended!
WARNING: ************************************************************
Starting nexus
[root@ubuntu24 local]# ss -tnlp |grep 8081
LISTEN 0 50 0.0.0.0:8081 0.0.0.0:* users:(("java",pid=5233,fd=998))
#会生成此文件,里面保存的是 web登录的初始密码,登录用户名是 admin
[root@ubuntu24 local]# cat /usr/local/sonatype-work/nexus3/admin.password
3c2903e7-36f6-4751-8ed5-6cad7f51d7b9
# 在浏览器中访问
# http://10.0.0.161:8081/
#配置服务脚本,使用systemctl 来进行服务管理
#https://help.sonatype.com/en/run-as-a-service.html
[root@ubuntu24 ~]# cat /lib/systemd/system/nexus.service
[Unit]
Description=nexus service
After=network.target
[Service]
Type=forking
LimitNOFILE=65536
ExecStart=/usr/local/nexus/bin/nexus start
ExecStop=/usr/local/nexus/bin/nexus stop
User=root
Restart=on-abort
[Install]
WantedBy=multi-user.target
[root@ubuntu24 ~]# systemctl daemon-reload
[root@ubuntu24 ~]# systemctl status nexus.service
○ nexus.service - nexus service
Loaded: loaded (/usr/lib/systemd/system/nexus.service; disabled; preset: enabled)
Active: inactive (dead)
#首次登录后修改密码,并选择支持匿名访问,做成公开库
# proxy 代理仓,如果 nexus 服务器上没有,则先去 maven 的官方仓库下载回来
# hosted 本地仓,如果 nexus 服务器上没有,不会去公网下载
# group 多个仓库的集合,仅支持 maven 仓库,yum 和 apt 仓库不能合并
# https://maven.aliyun.com 也有集合
#配置 maven-central 的公网地址为国内阿里云
https://maven.aliyun.com/repository/central
在 Maven 主机上测试自建的仓库
bash
[root@ubuntu24 ~]# cat /etc/maven/settings.xml
<mirror>
<id>mymaven</id>
<mirrorOf>*</mirrorOf>
<name>我的公共仓库</name>
<url>http://10.0.0.161:8081/repository/maven-public/</url>
</mirror>
#再次编译项目,可以看到是去自建的仓库中下载依赖包
[root@ubuntu ~]# cd spring-boot-helloworld/
[root@ubuntu spring-boot-helloworld]# mvn clean package -Dmaven.test.skip=true
#此时去查看 nexus 服务器,会看到有很多从阿里云上下载回来的包,可以供下次其它主机使用
bash
[root@ubuntu24 ~]# cat /etc/maven/settings.xml
<mirror>
<id>mymaven</id>
<mirrorOf>*</mirrorOf>
<name>我的公共仓库</name>
<url>http://10.0.0.161:8081/repository/maven-public/</url>
</mirror>
#再次编译项目,可以看到是去自建的仓库中下载依赖包
[root@ubuntu ~]# cd spring-boot-helloworld/
[root@ubuntu spring-boot-helloworld]# mvn clean package -Dmaven.test.skip=true
#此时去查看 nexus 服务器,会看到有很多从阿里云上下载回来的包,可以供下次其它主机使用
Nexus 配置 Apt 仓库
-
创建目录 /data/blobs
-
进入 nexus 配置界面,在 Blob Stores 页面点击 Create Blob Store ,创建一个存储,Type 选择 File,Name 填 ubuntu2404,Path 填 /data/blobs/ubuntu2204,点击保存
-
在 Repositories 页面点击 Create repository,选择 apt(proxy),在新页面中 Name 填 ubuntu2404,Distribution 填 jammy,Remote storage 填 https: //mirrors.aliyun.com/ubuntu/,Blob store 选择 ubuntu2404,点击保存
-
在Browse 页面选择刚创建的 ubuntu2404,点击 copy,复制源地址,然后修改一台 ubuntu 主机 的 /etc/apt/sources.list,将源指向自建的 nextus 服务器中的源地址
-
测试