2017-02-14 17 views
9

我正在編寫一個Java庫,我想用Gradle構建庫,然後從本地測試項目對其進行測試。包含使用Gradle構建的Java庫NoClassDefFoundError

我寧願使用Gradle 3.3來達到我的目的。 該庫應該爲Java5和更高版本構建。

到目前爲止,我build.gradle看起來是這樣的:

plugins { 
    id 'jvm-component' 
    id 'java-lang' 
} 

repositories { 
    mavenCentral() 
} 

model { 
    components { 
    main(JvmLibrarySpec) { 
     sources { 
     java { 
      dependencies { 
      module 'commons-codec:commons-codec:1.10' 
      module 'org.apache.httpcomponents:httpcore:4.4.6' 
      module 'org.apache.httpcomponents:httpclient:4.5.3' 
      } 
     } 
     } 

     api { 
     exports 'io.simplepush' 
     } 

     targetPlatform 'java5' 
    } 
    } 
} 

庫的源代碼位於src/main/java/io/simplepush/Notification.java並取決於build.gradle文件中所述的依賴關係。

建立圖書館與./gradlew build工作正常,並生成build/jars/main/jar/main.jar

然而,當我從運行的IntelliJ一個測試項目(包括main.jar進入測試項目後),我得到以下運行時錯誤:
Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/http/HttpEntity

似乎測試項目不知道我的庫所需的運行時依賴關係。

我不知道什麼是告訴測試項目關於我的庫的依賴關係的正確方法。 我不想要一個包含所有依賴關係的胖罐子。
列出測試項目本身中的所有依賴項也不是一個選項。
最好我希望庫本身告訴測試項目它需要哪些依賴關係。

+0

爲什麼不添加庫測試到庫本身? –

+0

因爲我想了解使用Gradle將庫引入項目的過程。 – tymm

+0

也許這個問題的接受答案將有所幫助:http://stackoverflow.com/questions/24975745/gradle-dependencies-compile-project-by-relative-path – vinegarbin

回答

2

我解決了它通過改變幾件事情。
感謝@Babl將我指向正確的方向。
我的新圖書館build.gradle看起來是這樣的:

plugins { 
    id 'java' 
    id 'maven-publish' 
} 

sourceCompatibility = 1.5 

repositories { 
    mavenLocal() 
    mavenCentral() 
} 

dependencies { 
    compile 'commons-codec:commons-codec:1.10' 
    compile 'org.apache.httpcomponents:httpcore:4.4.6' 
    compile 'org.apache.httpcomponents:httpclient:4.5.3' 
} 

publishing { 
    publications { 
    maven(MavenPublication) { 
     groupId 'io.simplepush' 
     artifactId 'project1-sample' 
     version '1.1' 

     from components.java 
    } 
    } 
} 

現在我可以將庫推到本地Maven倉庫與./gradlew publishToMavenLocal

該測試項目的build.gradle使用application插件並定義了一個主類(在我的情況下爲Hello)。然後我可以運行./gradlew installDist來生成一個可執行文件(請參閱Application plugin docs),它將所有依賴關係放入類路徑並運行良好。

group 'com.test' 
version '1.0-SNAPSHOT' 

apply plugin: 'java' 
apply plugin: 'application' 

repositories { 
    mavenLocal() 
    mavenCentral() 
} 

dependencies { 
    compile 'io.simplepush:project1-sample:1.1' 
} 

mainClassName = "Hello" 
+0

http://stackoverflow.com/help/someone-answers – LazerBanana

5

您創建的庫jar不包含IDE/Gradle可以解析爲能夠編譯/運行測試項目的任何依賴信息。我看到你正在使用Maven中央倉庫,所以你需要做的是將你的庫發佈到你的本地Maven倉庫,並且在測試項目中添加一個依賴信息(不是簡單的jar文件)。

因此,在庫和測試項目build.gradle添加一個maven本地存儲庫配置。

repositories { 
    mavenLocal() 
    mavenCentral() 
} 

現在您需要將庫發佈到本地存儲庫。當您使用gradle 3.3時,您可以使用Maven Publishing

於是在庫build.gradle中添加了一個maven發佈信息。

publishing { 
    publications { 
     maven(MavenPublication) { 
      groupId 'io.simplepush' 
      artifactId 'project1-sample' 
      version '1.1' 

      from components.java 
     } 
    } 
} 

Gradle「maven-publish」插件使得這很容易發佈到本地存儲庫,自動創建PublishToMavenLocal任務。 所以,你可以只運行

gradle publishToMavenLocal

將與所有的依賴性信息到本地Maven倉庫發佈您的圖書館。

然後你只需要一個庫信息添加到您的測試項目build.gradle

dependencies { 
     // other dependencies ..... 
     module 'io.simplepush:project1-sample:1.1' 
} 
+0

謝謝。這是我想要採取的方向。經過一些進一步的修改(刪除整個模型部分,在'build.gradle'文件的第一級指定'compile'的依賴關係並加載java插件),似乎會生成一個本地maven庫,它可以正確指定它的依賴關係它的pom文件。不過,我仍然得到同樣的錯誤。你可能會詳細說明如何正確生成一個可執行的jar與測試項目的gradle? – tymm

0

這指定的軟件倉庫進行檢查,從

repositories { 
    mavenCentral() 
} 

因此獲取的依賴關係,任何在dependecies{}將從上述那些中提取。

如果測試項目沒有與庫項目耦合,(@RaGe示例)新測試項目需要知道從何處獲取依賴關係 - 您需要使用首選方法發佈它。

之後,新的測試項目需要指定與在的build.gradle的首選配置(編譯...運行時間等)庫dependencies{}

之後根據IDE需要刷新類路徑和從指定倉庫之前,在庫的依賴(在這種情況下)指定的傳遞依賴將得到牽強從測試項目repositories{}


庫下載依賴的build.gradle

repositories { 
    mavenCentral() 
} 

dependencies { 
    module 'commons-codec:commons-codec:1.10' 
    module 'org.apache.httpcomponents:httpcore:4.4.6' 
    module 'org.apache.httpcomponents:httpclient:4.5.3' 
} 

測試項目的build.gradle

repositories { 
    mavenCentral() repository to fetch transitives 
    mavenLocal() or any other repo that you published the library to 
} 

dependencies { 
    pref-conf librarygroup:name:version 
} 

可以使用的想法或偏食的gradle中的插件gradle ideagradle eclipseClasspath任務與新加入的依賴刷新它。

有了這個解決方案,你不應該需要在圖書館內包裝傳遞依賴,

PS。你說你想要可執行jar後,我只是感到困惑。

相關問題