标签:总结 Maven 依赖 classpath 离线 IDEA compile 传递性 范围
IDEA现场离线环境问题总结 因为现场Java开发的离线环境,经常会导致引入jar等各种环境问题,现将离线开发过程中遇到的环境问题进行总结。 问题1:IDEA控制台报错,如下所示:Process terminated
答案分析:一般情况下,该种情况是有maven的配置问题导致的。比如配置文件settings.xml中有错误(例如标签不匹配,缺少开始标签或结束标签、缩进或者空格有问题),或者idea中的maven配置有问题,比如对应的setting或repository文件配置不正确,或者在设置离线模式的情况下设定的repository文件夹是空的等情况。
此外,如果maven配置正常,只是设定为离线模式了,但是控制台依然报该错误,可能的原因是项目代码还未引入maven项目,此时的操作是取消离线模式,然后在外网机环境更新对应的依赖即可解决。
问题2:IDEA环境Maven引入报错,如下图1所示:
图1
答案分析:这种报错比较明显就是仓库中缺陷对应的包所导致。在此处要引入传递性依赖的概念。
讲述传递性依赖的概念之前要先说明下依赖范围。
Maven在编译项目主代码的时候需要使用一套classpath,假如编译项目主代码的时候需要用到spring-core包,该文件以依赖的方式被引入到classpath中。其次,Maven在编译和执行测试的时候会使用另外一套classpath。测试程序Junit也以依赖的方式引入到测试使用的classpath中,不同的是这里的依赖范围是test。最后,实际运行Maven项目的时候,又会使用一套classpath,但测试程序Junit就不需要。
依赖范围就是用来控制依赖与这三种classpath(编译classpath、测试classpath、运行classpath)的关系,Maven有以下几种依赖范围:
compile:编译依赖范围。如果没有指定,就会默认使用该依赖范围。使用此依赖范围的Maven依赖,对于编译、测试、运行三种classpath都有效。典型的例子是spring-core,在编译、依赖和运行的时候都需要使用该依赖。
test:测试依赖范围。使用此依赖范围的Maven依赖,只对于测试classpath有效。典型的例子是Junit,它只在编译测试代码及运行测试的时候才需要。
provided:已提供依赖范围。使用此依赖范围的Maven依赖,对于编译和测试classpath有效,但在运行时无效。典型的例子是servlet-api,编译和测试项目的时候需要该依赖,但在运行项目的时候,由于容器已经提供,就不需要Maven重复地引入一遍。
runtime:运行时依赖范围。使用此依赖范围的Maven依赖,对于测试和运行classpath有效,但在编译主代码时无效。典型的例子是JDBC驱动实现,项目主代码的编译只需要JDK提供的JDBC接口,只有在执行测试或者运行项目的时候才需要实现上述接口的具体JDBC驱动。
system:系统依赖范围。该依赖与三种classpath的关系,和provided依赖范围完全一致。但是,使用system范围的依赖时必须通过systemPath元素显示地指定依赖文件的路径。由于此类以来不是通过Maven仓库解析的,而且往往与本机系统绑定,可能造成构建的不可移植,因此应该谨慎使用。systemPath元素可以引用环境变量,如:
<dependency>
<groupId>javax.sql</groupId>
<artifactId>jdbc-stdext</artifactId>
<version>javax.sql</version>
<scope>system</scope>
<systemPath>${java.home}/lib/rt.jar</systemPath>
</dependency>
表1 依赖范围描述
依赖范围(Scope) | 对于编译classpath有效 | 对于测试classpath有效 | 对于运行时classpath有效 | 例子 |
---|---|---|---|---|
compile | Y | Y | Y | spring-core |
test | - | Y | - | JUint |
provided | Y | Y | - | servlet-api |
runtime | - | Y | Y | JDBC驱动实现 |
system | Y | Y | - | 本地的,Maven仓库之外的类库文件 |
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.1.1</version>
</dependency>
该依赖没有声明依赖范围,那么其依赖范围就是默认的compile。例如项目TestProgram有一个compile范围的spring-core依赖,spring-core有一个compile范围的commons-logging依赖,那么commons-logging就会成为项目TestProgram的compile范围依赖,commons-logging是项目TestProgram的一个传递性依赖,如下图2所示:
图2 传递性依赖
有了传递性依赖机制,在使用Spring Framework的时候就不用去考虑它依赖了什么,也不用担心引入多余的依赖。Maven会解析各个直接依赖的POM,将那些必要的间接依赖,以传递性依赖的形式引入到当前的项目中。
依赖范围不仅可以控制依赖与三种classpath的关系,还对传递性依赖产生影响。上面的例子中,项目TestProgram对于spring-core的依赖范围是compile,spring-core对于commons-logging的依赖范围是compile,那么项目TestProgram对于commons-logging这一传递性依赖的范围也就是compile。假设A依赖于B,B依赖于C,我们即认为A对于B是第一直接依赖,B对于C是第二直接依赖,A对于C是传递性依赖。第一直接依赖的范围和第二直接依赖的范围决定了传递性依赖的范围,如表2所示,最左边一行表示第一直接依赖范围,最上面一行表示第二直接依赖范围,中间的交叉单元格则表示传递性依赖范围。
表2 依赖范围影响传递性依赖
compile | test | provided | runtime | |
---|---|---|---|---|
compile | compile | ------ | ------ | compile |
test | test | ------ | ------ | test |
provided | provided | ------ | provided | provided |
runtime | runtime | ------ | ------ | runtime |
-Dmaven.wagon.http.ssl.insecure=true -Dmaven.wagon.http.ssl.allowall=true
问题4:IDEA 错误: 找不到或无法加载主类
答案分析:可能的原因:1) 未能成功编译。操作:Build->Rebuild Project。一般情况下重新编译后即可正常启动。
2) 缓存问题。操作:File->Invalidate Caches/Restart 。选择Invalidate and REstart 或者选择Invalidate,然后清除掉缓存,接着Rebuild Project。
问题5:1) 明明maven库里有对应的jar包,但项目代码在却找不到。
2) 项目有以下在编译时提示类似以下报错:
Cannot access central (https://repo.maven.apache.org/maven2) in offline mode and the artifact dom4j:dom4j:pom:1.6.1 has not been downloaded from it before.
答案分析:解决方法,直接删除本地仓库中对应jar包所属文件夹的以.lastUpdated和.repositories为后缀的文件(没有以.lastUpdated为后缀的,仅删除以.repositories为后缀的文件即可)。在实际操作中要删除的该类文件可能会比较多,这点需要一定的耐心,本人测试过将外网机同一项目环境中运行正常的本地仓库拷贝到内网机中,有时依然需要这样操作。
原因分析:出现.lastUpdated文件一般情况下是由于网速慢、断网等原因导致jar包下载不下来或不完整导致出现该文件的,.repositories文件的作用相当于本地Maven仓库缓存了jar/pom的情况下修改了maven配置文件(settings.xml)后依然会去远程仓库获取。将其删除后就不会去这类文件中找远端仓库地址进行更新,而是直接引用了现有jar包,该问题也就解决了。
标签:总结,Maven,依赖,classpath,离线,IDEA,compile,传递性,范围 来源: https://www.cnblogs.com/ITBlock/p/15485426.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。