最近在接触公司内一个Maven项目需要配置公司内部的私有仓库,可以借此机会熟悉下Java开发大名鼎鼎的Maven,网上不少关于Maven的配置资料都是基于Windows环境,基于OSX和Linux的教程很少,因此在环境搭建及配置中也遇到不少问题,在成功搭建这个环境过程中也学到了不少东西,借此记录。
/Users/lijiahao/apache-maven-3.3.9
。 ~/.bash_profile
内添加如下: export M2_HOME=/Users/lijiahao/apache-maven-3.3.9 export PATH=$PATH:$M2_HOME/bin
~/.bash_profile
并生效,此时全局命令就可以使用 mvn
了: $ source ~/.bash_profile $ mvn -v Apache Maven 3.3.9 (bb52d8502b132ec0a5a3f4c09453c07478323dc5; 2015-11-11T00:41:47+08:00) Maven home: /Users/lijiahao/apache-maven-3.3.9 Java version: 1.8.0_112, vendor: Oracle Corporation Java home: /Library/Java/JavaVirtualMachines/jdk1.8.0_112.jdk/Contents/Home/jre Default locale: zh_CN, platform encoding: UTF-8 OS name: "mac os x", version: "10.14.6", arch: "x86_64", family: "mac"
maven的配置文件存放在 /Users/lijiahao/apache-maven-3.3.9/conf/settings.xml
文件下,原始的xml文件内容很简单,每一项都有官方的详细注释:
<?xml version="1.0" encoding="UTF-8"?> <!-- | This is the configuration file for Maven. It can be specified at two levels: | | 1. User Level. This settings.xml file provides configuration for a single user, | and is normally provided in ${user.home}/.m2/settings.xml. | | NOTE: This location can be overridden with the CLI option: | | -s /path/to/user/settings.xml | | 2. Global Level. This settings.xml file provides configuration for all Maven | users on a machine (assuming they're all using the same Maven | installation). It's normally provided in | ${maven.home}/conf/settings.xml. | | NOTE: This location can be overridden with the CLI option: | | -gs /path/to/global/settings.xml | | The sections in this sample file are intended to give you a running start at | getting the most out of your Maven installation. Where appropriate, the default | values (values used when the setting is not specified) are provided. | |--> <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>/path/to/local/repo</localRepository> --> <!-- interactiveMode | This will determine whether maven prompts you when it needs input. If set to 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 | 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> --> <!-- pluginGroups | This is a list of additional group identifiers that will be searched when resolving plugins by their prefix, i.e. | when invoking a command line like "mvn prefix:goal". Maven will automatically add the group identifiers | "org.apache.maven.plugins" and "org.codehaus.mojo" if these are not already contained in the list. |--> <pluginGroups> <!-- pluginGroup | Specifies a further group identifier to use for plugin lookup. <pluginGroup>com.your.plugins</pluginGroup> --> </pluginGroups> <!-- proxies | This is a list of proxies which can be used on this machine to connect to the network. | Unless otherwise specified (by system property or command-line switch), the first proxy | specification in this list marked as active will be used. |--> <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> <!-- servers | This is a list of authentication profiles, keyed by the server-id used within the system. | Authentication profiles can be used whenever maven must make a connection to a remote 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> <!-- mirrors | This is a list of mirrors to be used in downloading artifacts from remote repositories. | | It works like this: a POM may declare a repository to use in resolving certain artifacts. | However, this repository may have problems with heavy traffic at times, so people have mirrored | it to several places. | | That repository definition will have a unique id, so we can create a mirror reference for that | repository, to be used as an alternate download site. The mirror site will be the preferred | server for that repository. |--> <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> --> </mirrors> <!-- profiles | This is a list of profiles which can be activated in a variety of ways, and which can modify | the build process. Profiles provided in the settings.xml are intended to provide local machine- | specific paths and repository locations which allow the build to work in the local environment. | | For example, if you have an integration testing plugin - like cactus - that needs to know where | your Tomcat instance is installed, you can provide a variable here such that the variable is | dereferenced during the build process to configure the cactus plugin. | | As noted above, profiles can be activated in a variety of ways. One way - the activeProfiles | section of this document (settings.xml) - will be discussed later. Another way essentially | relies on the detection of a system property, either matching a particular value for the property, | or merely testing its existence. Profiles can also be activated by JDK version prefix, where a | value of '1.4' might activate a profile when the build is executed on a JDK version of '1.4.2_07'. | Finally, the list of active profiles can be specified directly from the command line. | | NOTE: For profiles defined in the settings.xml, you are restricted to specifying only artifact | repositories, plugin repositories, and free-form properties to be used as configuration | variables for plugins in the 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', 'user-jdcasey', '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 system 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> <!-- activeProfiles | List of profiles that are active for all builds. | <activeProfiles> <activeProfile>alwaysActiveProfile</activeProfile> <activeProfile>anotherAlwaysActiveProfile</activeProfile> </activeProfiles> --> </settings>
在原有 settings.xml
的基础上,为了能达到可以访问私有仓库的目的,几个关键字段如下: repositories
、 mirrors
,指定私服仓库:
<repositories> <repository> <id>nexus</id> <url>https://127.0.0.0:8440/repository/maven-public/</url> </repository> </repositories>
Maven根据如上配置,会自动从私有仓库中下载构件,但是,如果私服中没有对应构件,还是会访问中央仓库,但是我们在Maven构件项目时,只是希望本地构件Maven项目时,仅仅只是访问Nexus,不希望访问中央仓库,访问中央仓库应该是Nexus的事,不是我们本地Maven配置的事,为了达到这个目标,我们还需要配置镜像:
<mirrors> <mirror> <id>nexus</id> <mirrorOf>*</mirrorOf> <url>https://127.0.0.0:8443/repository/maven-public/</url> </mirror> </mirrors>
通过镜像配置,创建一个匹配任何仓库的镜像,镜像的地址变为私服,这样Maven对于构件的请求都会转到Nexus中去,没有构件,私有仓库自己访问中央仓库缓存,本地只需要从私有仓库下载构件即可。
完整的 settings.xml
配置如下:
<?xml version="1.0" encoding="UTF-8"?> <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"> <!-- 将maven的本地下载仓库重新指向新目录,默认值是 ${user.home}/.m2/repository --> <localRepository>/Users/lijiahao/apache-maven-3.3.9/repos</localRepository> <pluginGroups> </pluginGroups> <proxies> </proxies> <servers> <server> <id>nexus</id> <username>test</username> <password>test</password> </server> </servers> <mirrors> <mirror> <id>nexus</id> <!-- 所有的构建均从私有仓库中下载,*代表所有,也可以写成central --> <mirrorOf>*</mirrorOf> <url>https://127.0.0.0:8443/repository/maven-public/</url> </mirror> </mirrors> <profiles> <profile> <id>nexus</id> <repositories> <repository> <id>central</id> <url>http://central</url> <releases> <enabled>true</enabled> </releases> <snapshots> <enabled>true</enabled> </snapshots> </repository> </repositories> <pluginRepositories> <pluginRepository> <id>central</id> <url>http://central</url> <releases> <enabled>true</enabled> </releases> <snapshots> <enabled>true</enabled> </snapshots> </pluginRepository> </pluginRepositories> </profile> </profiles> <!-- 激活 --> <activeProfiles> <activeProfile>nexus</activeProfile> </activeProfiles> </settings>
基本上安装了maven和配置了settings.xml之后就可以直接在maven项目的执行相关操作了,但是具体操作时发现,执行 mvn
命令时会报错:
$ mvn clean [INFO] BUILD FAILURE [INFO] ------------------------------------------------------------------------ [INFO] Total time: 0.706 s [INFO] Finished at: 2019-12-12T15:16:05+08:00 [INFO] Final Memory: 9M/123M [INFO] ------------------------------------------------------------------------ [ERROR] Plugin org.apache.maven.plugins:maven-clean-plugin:2.5 or one of its dependencies could not be resolved: ... ...
根据报错信息可以得知是相关依赖缺失,导致编译失败,检查 settings.xml
下的 localRepository
配置的目录,发现依赖确实没有下载下来,那是什么原因呢?我先把镜像换成maven官方地址:
<mirror> <id>central</id> <name>Maven Repository Switchboard</name> <url>http://repo1.maven.org/maven2/</url> <mirrorOf>central</mirrorOf> </mirror>
重新执行 mvn clean
,发现可以正常安装构件,再仔细对比官方地址与私有仓库的地址,发现私有仓库地址为 https
开头,之后通过查询maven官方得到 答案 :如果远程服务器为HTTPS,还需要额外的验证信息,也就是需要导入私有仓库的证书,才能从私有仓库下载构件。在使用 NEXUS
进行私有仓库搭建时会有一个 nexus.crt
的证书,我们接下来需要把证书导入到我们本地的Java环境中: 我当前的jdk版本为 1.8.0
:
$ echo $JAVA_HOME /Library/Java/JavaVirtualMachines/jdk1.8.0_112.jdk/Contents/Home
使用keytool导入证书到jdk安装目录下的 cacerts
中,这里我对证书使用了一个名为server的别名:
$ sudo keytool -import -file ./nexus.crt -keystore $JAVA_HOME/jre/lib/security/cacerts -alias server Enter keystore password:
注:
keytool 错误: java.io.IOException: Keystore was tampered with, or password was incorrect
错误,Linux下暂时还没验证此问题。 导入证书后,查询证书是否正确导入:
$ keytool -list -keystore $JAVA_HOME/jre/lib/security/cacerts | grep server 输入密钥库口令: changeit server, 2019-12-12, trustedCertEntry,
导入证书后再重新执行 mvn clean
,发现依赖已经可以正常安装,mvn命令已经可以正常使用。
通过此次实践,我对Maven的理解是:Maven是Java开发的项目管理工具,跟nodejs中最常用的 NPM
类似,都是通过项目下一个配置文件(node环境里就是package.json,Java里就是pom.xml)来管理项目下需要使用的依赖,区别在于:
(完)
原创不易,如果觉得这篇文章对你有帮助,不如赏杯咖啡吧
微信
支付宝