关于maven3:聊聊springboot项目引用第三平台私有jar踩到的坑

前言最近和敌人闲聊,他说他遇到一个问题,他援用了第三方公司公有API包,他在本地我的项目启动没问题,打包运行却找不到这个API包,于是我就问他怎么援用这个jar。 他工程项目第三jar寄存的地位相似如下在pom做如下援用 <dependency> <groupId>org.example</groupId> <artifactId>demo-api</artifactId> <version>1.0-SNAPSHOT</version> <scope>system</scope> <systemPath>${project.basedir}/lib/demo-api.jar</systemPath> </dependency>pom打包插件用springboot自带的插件 <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <executions> <execution> <goals> <goal>repackage</goal> </goals> </execution> </executions> </plugin> </plugins> </build>看到这个插件,大略就晓得问题所在了,springboot默认的打包插件是不会把systemscope的jar打进springboot我的项目的BOOT-INF/lib/。 注: springboot我的项目默认会援用BOOT-INF/lib/外面的jar 于是我就跟敌人说,不要用systemscope了,间接搭建maven私仓,而后把第三方jar上传到私仓中,pom做如下援用 <dependency> <groupId>org.example</groupId> <artifactId>demo-api</artifactId> <version>1.0-SNAPSHOT</version> </dependency>敌人给回复是公司没有私仓,我一脸懵逼,我就问他应该不至于吧,再次确认,失去他同样的回复后。后边就提供了下边的几种计划,让他参考抉择 springboot如何援用没有公布到私仓的第三jar整体思路:因为springboot提供的打包插件,默认是会把位于BOOT-INF/lib/外面的jar编译成class文件而后供我的项目援用。因而咱们只需确保BOOT-INF/lib/外面含有咱们要援用的第三方jar即可 计划一:pom指定jar范畴为system+springboot插件退出includeSystemScope标签的属性为true示例: <dependency> <groupId>org.example</groupId> <artifactId>demo-api</artifactId> <version>1.0-SNAPSHOT</version> <scope>system</scope> <systemPath>${project.basedir}/lib/demo-api.jar</systemPath> </dependency> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <includeSystemScope>true</includeSystemScope> </configuration> <executions> <execution> <goals> <goal>repackage</goal> </goals> </execution> </executions> </plugin> </plugins> </build>计划二:pom指定jar范畴为system+resources标签引入要蕴含的jar <dependency> <groupId>org.example</groupId> <artifactId>demo-api</artifactId> <version>1.0-SNAPSHOT</version> <scope>system</scope> <systemPath>${project.basedir}/lib/demo-api.jar</systemPath> </dependency> <build> <resources> <resource> <directory>${project.basedir}/lib</directory> <targetPath>BOOT-INF/lib/</targetPath> <includes> <include>**/*.jar</include> </includes> </resource> </resources> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <executions> <execution> <goals> <goal>repackage</goal> </goals> </execution> </executions> </plugin> </plugins> </build>计划三:间接将第三方jar打进要公布的本地仓库上图是maven官网的仓库流程图,其实对maven比拟相熟的敌人应该会晓得,maven会先从本地仓库找jar,本地仓库找不到jar,就会再从私仓(如果有搭建私仓)外面找,私仓没有再从地方仓库找,而后找到的jar再寄存到本地仓库。 ...

June 15, 2021 · 1 min · jiezi

关于maven3:centos7-mvn-上传jar到私服

遇到如下问题 “Failed to transfer file: http://skf-nexus.xxxxx.com/re... Return code is: 401”找一台有maven的机器批改配置[root@dev-technology-215l ~]# cat /usr/local/apache-maven-3.3.9/conf/settings.xml<settings> <mirrors> <!--给定仓库的下载镜像。 --> <mirror> <!--该镜像的惟一标识符。id用来辨别不同的mirror元素。 --> <id>xxxxx</id> <!--镜像名称 --> <name>Nexus xxxxx</name> <!--该镜像的URL。构建零碎会优先思考应用该URL,而非应用默认的服务器URL。 --> <url>http://nexus.xxxxx.com/repository/xxxxx-maven-central/</url> <!--被镜像的服务器的id。例如,如果咱们要设置了一个Maven地方仓库(http://repo1.maven.org/maven2)的镜像,--> <!--就须要将该元素设置成central。这必须和地方仓库的id central完全一致。 --> <mirrorOf>central</mirrorOf> </mirror> </mirrors> <profiles> <profile> <id>jdk-1.8</id> <activation> <activeByDefault>true</activeByDefault> <jdk>1.8</jdk> </activation> <properties> <maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.target>1.8</maven.compiler.target> <maven.compiler.compilerVersion>1.8</maven.compiler.compilerVersion> </properties> </profile> <profile> <id>dev</id> <repositories> <repository> <id>nexus</id> <url>http://skf-nexus.xxxxx.com/repository/xxxxx-release/</url> <releases> <enabled>true</enabled> </releases> <snapshots> <enabled>true</enabled> </snapshots> </repository> </repositories> </profile> </profiles> <activeProfiles> <activeProfile>dev</activeProfile> </activeProfiles> <servers> <server> <id>releases</id> <username>admin</username> <password>xxxxx-0312</password> </server> <server> <id>snapshots</id> <username>admin</username> <password>xxxxx-0312</password> </server> </servers> <distributionManagement> <repository> <id>xxxxx-releases</id> <name>Nexus Release Repository</name> <url>http://skf-nexus.xxxxx.com/repository/xxxxx-release/</url> </repository> <snapshotRepository> <id>snapshots</id> <name>Nexus Snapshot Repository</name> <url>http://skf-nexus.xxxxx.com/repository/snapshots/</url> </snapshotRepository> </distributionManagement></settings>jar 包上传命令mvn deploy:deploy-file -DgroupId=com.csii.pe.http -DartifactId=security -Dversion=1.3 -Dpackaging=jar -Dfile="/tmp/maventest/com-csii-pe-http-security-1.3.jar" -Durl=http://skf-nexus.xxxxx.com/re... -DrepositoryId=releases

October 20, 2020 · 1 min · jiezi

Maven多模块结构下版本管理的正确姿势CI-Friendly-Versions-revision

在使用Maven多模块结构工程时,配置版本是一个比较头疼的事。继承版本,依赖版本,自身版本,都需要单独定义,很是麻烦。但其实Maven已经提供了这种CI版本的管理方式,下面来介绍具体用法。 从Maven 3.5.0-beta-1版本开始,就可以使用${revision}, ${sha1} 和 ${changelist}作为占位符来替换pom文件了。 注意:Idea下使用${revision}定义Parent版本时会提示错误“Reports that usage of properties in modules parent definition is prohibited”,但并不影响使用,只是Idea不支持这种写法而已。 单模块项目<project> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.apache</groupId> <artifactId>apache</artifactId> <version>18</version> </parent> <groupId>org.apache.maven.ci</groupId> <artifactId>ci-parent</artifactId> <name>First CI Friendly</name> <version>${revision}</version> ...</project>这种情况比较简单,只使用了${revision}来替换版本。 还可以用另一种动态添加参数的方式来指定版本 $ mvn -Drevision=1.0.0-SNAPSHOT clean package-D代表设置环境变量 -D,--define <arg> Define a system property或者在(父)项目的properties中定义版本: <project> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.apache</groupId> <artifactId>apache</artifactId> <version>18</version> </parent> <groupId>org.apache.maven.ci</groupId> <artifactId>ci-parent</artifactId> <name>First CI Friendly</name> <version>${revision}</version> ... <properties> <revision>1.0.0-SNAPSHOT</revision> </properties></project>多模块项目现在来看看多模块构建的情况。有一个父项目和一个或多子模块。父pom将如下所示: <project> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.apache</groupId> <artifactId>apache</artifactId> <version>18</version> </parent> <groupId>org.apache.maven.ci</groupId> <artifactId>ci-parent</artifactId> <name>First CI Friendly</name> <version>${revision}</version> ... <properties> <revision>1.0.0-SNAPSHOT</revision> </properties> <modules> <module>child1</module> .. </modules></project>子模块配置: ...

May 24, 2019 · 1 min · jiezi

Maven-中optionaltrueoptional和scopeprovidedscope之间的区别

依赖管理是maven提供的主要功能之一。无论我们需要什么依赖,我们只需将它们添加到POM.xml中。由于maven,所有必要的类和资源都会自动添加到项目的classpath中。 在添加依赖项时,我们可以使用optional标志,或将scope设置为“provided”。在这两种情况下,依赖关系都将在声明它们的模块的classpath中,但是使用将它们定义为依赖关系的模块不会在其他项目中传递它们,即不会形成依赖传递。 从语义来上理解optional可选的,可以理解为此功能/此依赖可选,如果不需要某项功能,可以不引用这个包。 scope provided提供的,可以理解为此包不由我直接提供,需要调用者/容器提供。 举个例子说明二者的使用场景和区别optional现开发了一个类似Hibernate的框架,叫Summer吧,致敬下Spring,提供了多种数据库方言的支持:mysql/oracle/db2/postgresql...每种数据库支持也独立了一个module,Summer的依赖中配置了每种数据库的支持包:summer-mysql-support/summer-oracle-support... 但是实际引用此框架/依赖时,并不需要所有数据库方言的支持。此时可以把数据库的支持包都配置为可选的<optional>true</optional>。引用此框架时,只需按需引入自己需要的方言支持包即可,避免了冗余繁杂的依赖,也降低了jar包冲突的风险。 scope provided现有一普通Web工程,必然会用到servlet-api这个包。但是实际上这个包一定是由容器提供的,因为我们这个web会部署到容器内,容器会提供servlet-api,如果此时项目中再引用的话就会造成重复引用,会有版本不一致的风险。 总结二者从功能来看,都做到了依赖不传递。但在语义上表示不同,使用时按场景选择就好。 参考https://medium.com/@danismaz.furkan/difference-between-optional-true-optional-and-scope-provided-scope-7404ec24fb59https://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html#Dependency_Scopehttps://maven.apache.org/guides/introduction/introduction-to-optional-and-excludes-dependencies.html

May 22, 2019 · 1 min · jiezi

自定义SpringBoot项目的Maven原型

前言:每次创建一个简单的项目,然后在像里面添加一些东西, 难免有些麻烦, 项目的骨架每次都是大同小异, 那么maven刚好可以提供模板可以每次对这个模板进行简单的修改, 就能实现公共项目的构建了。网上有很多博客提供了方案,但是我也跟着做了,大多是写的模模糊糊,或者这个抄袭那个, 最终出来的还不是想要的结果。对初学者不太友好。那么如何构建这个maven模板呢?提供以下两种方案。方案一通过maven创建一个项目执行mvn命令mvn archetype:generate -DgroupId=com.congitationsoft -DartifactId=maven-common-test1 -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false (亦可以通过编译器直接创建,没有影响,个人习惯) 生成项目如上图。通过编译器打开项目(亦可不用编译器打开,修改目录结构)构建所需项目(因演示需要,仅做简单尝试)对项目添加resources/static 和resources/template目录并添加一个demo.js和demo.html 文件,并且pom中的junit版本有3.8.1更换为4.12。对项目进行本地maven库安装进入到项目目录:执行以下命令:1. mvn clean2. mvn archetype:create-from-project 3. cd target/generated-sources/archetype/4. mvn install5. mvn archetype:crawl6. mvn archetype:update-local-catalog 7. cd ../../../../8. mvn archetype:generate这时会得到如图所示的结果: 选择13就会生成刚刚创建的自定义的maven脚手架。结果通过编译器打开可以看到所有新构建的内容已经存在。方案二 (源码:GitHub地址 )执行mvn命令mvn archetype:generate -DgroupId=com.congitationsoft -DartifactId=maven-common-springboot -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false执行命令mvn clean compile 和 mvn clean test-compile 对main目录和test目录中的内容进行编译, 否则这里会报找不到主类的错误。然后将项目导入到idea编译器中,并添加一些目录内容,参照:自定义Maven SpringBoot Web项目骨架添加到本地maven库在项目根路径下执行:1. mvn clean install2. mvn archetype:crawl3. mvn archetype:update-local-catalog 4. mvn archetype:generate结语如果有特别的需要, 建议查看官方文档。如果有问题,请在留言区留言。

February 27, 2019 · 1 min · jiezi

maven 多仓库和镜像设置

为什么使用镜像当maven在本地找不到包的时候,就尝试从中央仓库(https://repo1.maven.org/maven2/)获取,有的时候我们访问外网太慢了,我们就从镜像仓库(别的仓库或者自己的私有仓库)获取。设置镜像<mirror> <id>tz-mirror</id> <mirrorOf>external:,!mmkj</mirrorOf> <name>tz test nexus repository</name> <url>http://xxxxx:30003/repository/maven-proxy</url></mirror>id 唯一标识mirrorOf 指定镜像的规则。就是什么情况会从镜像仓库拉取,而不是从原本的仓库拉取 可选项参考链接: 匹配所有external:* 除了本地缓存之后的所有仓库repo,repo1 repo 或者 repo1。 这里repo指的是仓库的id,下文会提到*,!repo1 除了repo1的所有仓库name 名称描述url 地址上述的例子除了mmkj仓库之外,其他的全从自己的私有仓库获取(仓库我做了代理,会自动从中央仓库https://repo1.maven.org/maven2/获取).多仓库配置参考链接 第三方包,自己公司的包等除了手动install:install-file导入之外,最好的办法就是搭建自己公司的私有仓库,这里推荐使用nexus, 这样除了中央仓库之外就需要设置自己的仓库了设置多仓库有2个方法:pom设置(java的pom文件)<project>… <repositories> <repository> <id>my-repo1</id> <name>your custom repo</name> <url>http://jarsm2.dyndns.dk</url> </repository> <repository> <id>my-repo2</id> <name>your custom repo</name> <url>http://jarsm2.dyndns.dk</url> </repository> </repositories>…</project>这里的id就是镜像mirrorOf使用的setting设置(${user.home}/.m2/settings.xml)<settings> … <profiles> … <profile> <id>myprofile</id> <repositories> <repository> <id>my-repo2</id> <name>your custom repo</name> <url>http://jarsm2.dyndns.dk</url> </repository> … </repositories> </profile> … </profiles> <activeProfiles> <activeProfile>myprofile</activeProfile> </activeProfiles> …</settings>激活配置文件除了放在activeProfiles中之外,也可以使用mvn的参数mvn -Pmyprofile …

December 17, 2018 · 1 min · jiezi