今天編譯maven的時候出現(xiàn)問題了
mvn clean compile
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.3:compile (default-compile) on project iot_push_server: Compilation failure: Co
mpilation failure:
[ERROR] /D:/iot_push-master/iot_push_server/src/main/java/com/lxr/iot/bootstrap/BaseApi.java:[3,31] 程序包com.sun.istack.internal不存在
[ERROR] /D:/iot_push-master/iot_push_server/src/main/java/com/lxr/iot/bootstrap/BaseApi.java:[74,35] 找不到符號
[ERROR] 符號: 類 NotNull
[ERROR] 位置: 接口 com.lxr.iot.bootstrap.BaseApi
[ERROR] /D:/iot_push-master/iot_push_server/src/main/java/com/lxr/iot/bootstrap/BaseApi.java:[74,49] 找不到符號
[ERROR] 符號: 類 NotNull
[ERROR] 位置: 接口 com.lxr.iot.bootstrap.BaseApi
[ERROR] /D:/iot_push-master/iot_push_server/src/main/java/com/lxr/iot/bootstrap/BaseApi.java:[74,81] 找不到符號
[ERROR] 符號: 類 NotNull
[ERROR] 位置: 接口 com.lxr.iot.bootstrap.BaseApi
[ERROR] -> [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/MojoFailureException
[ERROR]
[ERROR] After correcting the problems, you can resume the build with the command
[ERROR] mvn <goals> -rf :iot_push_server
這里最關(guān)鍵的提示是:
程序包 com.sun.istack.internal 不存在
我看了下ide访锻,沒有報錯室叉,可以點到com.sun.istack.internal
這個包里面骗炉!
這就有點麻煩了仇味。
首先呻顽,大概猜下為啥這個包不存在
我們是在編譯java文件的時候需要依賴這個包中的class,也就是mvn compile
調(diào)用的編譯程序的classpath中沒有包含 com.sun.istack.internal
這個包丹墨,而ide中卻包含了這個包廊遍。而通過ide,我們觀察到 com.sun.istack.internal
這個包在 ${MAVEN_HOME}/jre/lib/rt.jar
這個jar中带到,所以我們可以得出一個大致的結(jié)論:
mvn compile
調(diào)用的編譯程序的classpath中缺少${MAVEN_HOME}/jre/lib/rt.jar
這個jar包
那么下一步昧碉,我們應(yīng)該通過日志,去觀察 mvn compile
的編譯程序所依賴的classpath
通過maven 命令揽惹,執(zhí)行以下命令debug被饿。
mvn compile -X -e
控制臺日志
[INFO] --- maven-compiler-plugin:3.3:compile (default-compile) @ iot_push_server ---
[DEBUG] Configuring mojo org.apache.maven.plugins:maven-compiler-plugin:3.3:compile from plugin realm ClassRealm[plugin>org.apache.maven.plugins:maven-compiler
-plugin:3.3, parent: sun.misc.Launcher$AppClassLoader@33909752]
[DEBUG] Configuring mojo 'org.apache.maven.plugins:maven-compiler-plugin:3.3:compile' with basic configurator -->
[DEBUG] (f) basedir = D:\iot_push-master\iot_push_server
[DEBUG] (f) buildDirectory = D:\iot_push-master\iot_push_server\target
[DEBUG] (f) classpathElements = [XXXXXXXX some jar XXXXXXXX]
[DEBUG] (f) compileSourceRoots = [D:\iot_push-master\iot_push_server\src\main\java]
[DEBUG] (f) compilerId = javac
[DEBUG] (f) debug = true
[DEBUG] (f) encoding = UTF-8
[DEBUG] (f) failOnError = true
[DEBUG] (f) forceJavacCompilerUse = false
[DEBUG] (f) fork = false
[DEBUG] (f) generatedSourcesDirectory = D:\iot_push-master\iot_push_server\target\generated-sources\annotations
[DEBUG] (f) mojoExecution = org.apache.maven.plugins:maven-compiler-plugin:3.3:compile {execution: default-compile}
[DEBUG] (f) optimize = false
[DEBUG] (f) outputDirectory = D:\iot_push-master\iot_push_server\target\classes
[DEBUG] (f) project = MavenProject: com.lxr.iot:iot_push_server:1.0-SNAPSHOT @ D:\iot_push-master\iot_push_server\pom.xml
[DEBUG] (f) projectArtifact = com.lxr.iot:iot_push_server:jar:1.0-SNAPSHOT
[DEBUG] (f) session = org.apache.maven.execution.MavenSession@610db97e
[DEBUG] (f) showDeprecation = false
[DEBUG] (f) showWarnings = false
[DEBUG] (f) skipMultiThreadWarning = false
[DEBUG] (f) source = 1.8
[DEBUG] (f) staleMillis = 0
[DEBUG] (f) target = 1.8
[DEBUG] (f) useIncrementalCompilation = true
[DEBUG] (f) verbose = false
[DEBUG] -- end configuration --
[DEBUG] Using compiler 'javac'. (=======重要========)
[DEBUG] Source directories: [D:\iot_push-master\iot_push_server\src\main\java]
[DEBUG] Classpath: [D:\iot_push-master\iot_push_server\target\classes
D:\iot_push-master\iot_push_common\target\classes , XXXXXXXX some jar XXXXXXXX]
[DEBUG] Output directory: D:\iot_push-master\iot_push_server\target\classes
[DEBUG] Adding D:\iot_push-master\iot_push_server\target\generated-sources\annotations to compile source roots:
D:\iot_push-master\iot_push_server\src\main\java
[DEBUG] New compile source roots:
D:\iot_push-master\iot_push_server\src\main\java
D:\iot_push-master\iot_push_server\target\generated-sources\annotations
...
[DEBUG] Source roots:
[DEBUG] D:\iot_push-master\iot_push_server\src\main\java
[DEBUG] D:\iot_push-master\iot_push_server\target\generated-sources\annotations
[DEBUG] Command line options:(=======重要========)
[DEBUG] -d D:\iot_push-master\iot_push_server\target\classes -classpath XXXXXXXX some jar XXXXXXXX -sourcepath D:\iot_push-master\iot_push_server\src\main\java;D:\iot_push-master\iot_push_server\target\generated
-sources\annotations; -s D:\iot_push-master\iot_push_server\target\generated-sources\annotations -g -nowarn -target 1.8 -source 1.8 -encoding UTF-8
[DEBUG] incrementalBuildHelper#beforeRebuildExecution
[INFO] Compiling 31 source files to D:\iot_push-master\iot_push_server\target\classes
[DEBUG] incrementalBuildHelper#afterRebuildExecution
我們通過日志,發(fā)現(xiàn)兩個很關(guān)鍵的內(nèi)容
- 使用javac編譯程序
[DEBUG] Using compiler 'javac'.
- javac的classpath參數(shù)不包含 jdk的lib文件中所包含的jar包
[DEBUG] Command line options:
[DEBUG] -d D:\iot_push-master\iot_push_server\target\classes
-classpath ... -sourcepath
通過classpath,我們知道 javac會找兩個的classpath搪搏,一個是系統(tǒng)環(huán)境變量 CLASSPATH
,一個是參數(shù) -classpath
狭握,這里參數(shù)不包含classpath,那么必須在環(huán)境變量CLASSPATH
中尋找疯溺。
驗證:
我們在window中查找classpath
C:\Users\ezlhq> echo %classpath%
.;D:\java\jdk1.8.0_152\lib\dt.jar;D:\java\jdk1.8.0_152\lib\tools.jar;
對比 ide中的classpath
同時我們手動用javac 去編譯類
C:\Users\ezlhq>javac -verbose D:\iot_push-master\iot_push_server\src\main\java\com\lxr\iot\bootstrap\BaseApi.java
[解析開始時間 RegularFileObject[D:\iot_push-master\iot_push_server\src\main\java\com\lxr\iot\bootstrap\BaseApi.java]]
[解析已完成, 用時 24 毫秒]
[源文件的搜索路徑: .,D:\java\jdk1.8.0_152\lib\dt.jar,D:\java\jdk1.8.0_152\lib\tools.jar]
[類文件的搜索路徑: xxxx
果然驗證了我們之前的答案论颅。mvn調(diào)用javac去編譯我們應(yīng)用程序的時候,并沒有帶上 rt.jar
這個jar包
那么如何解決這個問題了?
- window修改全局變量后還得重啟才能生效囱嫩,考慮到還有其他開發(fā)人員恃疯,不可能人人都重啟電腦,故棄之
- javac -classpath的時候加上
rt.jar
通過maven-compiler-plugin 插件使用
修改pom:bootclasspath 參考
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
<!-- 過期的方法的警告
<compilerArgs>
<arg>-Xlint:deprecation</arg>
</compilerArgs> -->
<compilerArguments>
<!-- 是否輸出所有的編譯信息(包括類的加載等)-->
<!--<verbose />-->
<!-- 解決maven命令編譯報錯墨闲,因為rt.jar 和jce.jar在jre的lib下面今妄,不在jdk的lib下面,
導(dǎo)致maven找不到(java7以后會出現(xiàn)這個問題)鸳碧,將這2個jar包拷貝到j(luò)dk的lib下面估計也好使-->
<bootclasspath>${java.home}\lib\rt.jar;${java.home}\lib\jce.jar</bootclasspath>
</compilerArguments>
</configuration>
</plugin>
</plugins>
</pluginManagement>