簡體   English   中英

IntelliJ 如何能夠從命令行解決依賴關系並運行 spring 引導(maven)應用程序,這是不可能的?

[英]how IntelliJ is able to resolve dependencies and run a spring boot (maven) application while from the command line, it is not possible?

我很想知道 Intellij 如何解決依賴沖突? 讓我解釋一下我的情況。 我應該在 spring 啟動應用程序上工作。 它使用 Maven。 IntelliJ 可以毫無問題地構建和運行應用程序,但是當我制作 jar 文件時,

mvn clean package 

並運行 jar 文件

java -jar xxx.jar

我遇到了java.lang.NoSuchMethodError 一些依賴項沖突導致了它,我的應用程序使用了錯誤版本的 jar 文件。 我想知道 IntelliJ 如何找到包含該方法的正確 jar 文件,同時它使用相同的 pom.xml,我在使用 mvn 命令時遇到錯誤。 是否可以找到 IntelliJ 使用的每個 jar 文件的哪個版本 (我想用它來更正 pom 文件)

謝謝

當涉及到這些事情時,運行時和編譯時間之間存在很大差異。

編譯代碼(例如mvn package )和編寫代碼(例如,IntelliJ 正在做什么以確保您的編輯體驗良好;您使用的所有庫的自動完成對話框,如果您嘗試調用不存在的方法則會出錯,等等)是一回事(我們稱之為“寫時間”)。

運行你的代碼,就像java -jar xxx.jar是完全不同的。

maven 和你的依賴列表是一個寫時間的事情 Thus, maven and intellij know where to look for your dependencies, but when you run java -jar xxx.jar , that does not know where to look, and thus, your dependencies aren't found, and thus, NoClassDefFoundError occurs.

That's because that jar file that maven makes just contains your code, it is completely disconnected from your maven file (your maven stuff is not looked up when you run your code at all), and it does not contain your dependencies .

您必須單獨運送它們。 這個問題有3個解決方案:

  • Preferred solution: jar files contain a so-called manifest, which tells the JVM for example what the name of the main class is within that jar file. 它還可以包含類路徑(這實際上是使用java -jar運行 jar 文件時檢查的唯一類路徑;您不能指定-classpath參數)。 這使您可以部署您的應用程序,使您的應用程序安裝如下所示:
/usr/local/projects/YourApp/main-app.jar
/usr/local/projects/YourApp/dep/guava.jar
/usr/local/projects/YourApp/dep/mysql-jdbc-connector.jar
/usr/local/projects/YourApp/dep/jdbi.jar

等等,要運行這個應用程序,只需運行main-app.jar 這需要 main-app.jar 的清單包含以下條目:

Class-Path: dep/guava.jar dep/mysql-jdbc-connector.jar dep/jdbi.jar

運行 jar 時, Class-Path條目按空格分隔,然后相對於包含main-app.jar的目錄查找每個條目。 通過單獨發送 jars,可以輕松單獨更新或替換它們,並且部署新版本的速度要快得多(您只需發送已更改的 jar,而不是全部。許多應用程序具有數百 MB 的 deps ,而他們自己的 jar 最多只有幾 MB,例如在將 deps 從您的開發機器推送到測試服務器時會產生很大的不同!)

這導致了一個問題:如何讓 maven 將該類路徑條目放入 output jar 文件的清單中? maven-jar-plugin可以完成這項工作 - 有關更多詳細信息,請參閱此答案

  • 在你的 deps 中添加陰影(也稱為條帶化、fatjar 或 bigjar)

這是獲取所有部門的概念,重寫他們的名稱以避免版本沖突,然后制作一個包含所有內容的巨大 jar 文件。 它有一個相當大的缺點,即過程慢得多,尤其是當您需要將其推送到另一個系統進行測試時。 使用陰影插件來做到這一點。

  • 不要使用java -jar

java -jar x.jar無法工作,除非 jar 文件在其清單中有一個 Class-Path 條目,或者包含它需要的每個 dep。 However, you can also run your java code like so: java -cp main-app.jar:dep/guava.jar:dep/jdbi.jar:/dep/other-deps-here com.foo.YourMainApp . 這是.. 不方便,但您大概可以編寫 shell 腳本或類似的腳本。 這不是一個非常類似於 java 的解決方案,我不推薦它。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM