2010-07-28 51 views
0

我有這樣的相關性的情況:如何解決maven單車問題?

C( - >)B - > A - >Ç

其中B-> C表示該模塊C具有一個依賴於它的POM到B。 XML。

嗯......我想在C使用一個類的B,所以我必須把C-> B,而我收到一個錯誤的循環,你可以在上面看到...

你看到任何解決方法?我不能在C中從B移動這個類,因爲它已經使用了A中的一些類,並且會再次循環。

我試圖聲明一個接口IAlfa用C和B(阿爾法)(實現它,但是當我想使用它,我需要實例,如:

IAlfa alfa = new Alfa() 

所以我又需要進口阿爾法從B.

你覺得呢?

感謝。

回答

2

這種情況似乎是壞的類/庫組織的症狀。

似乎非常奇怪,你會合法地進入這樣的情況

如果你有一個的組成的完全控制(如果你想討論隨意更精確地解釋你如何安排你的類), B和C,至少可以做以下事情:

  1. 將A,B和C合併到一個單獨的庫中並完成它。 (不建議 - 它會使好的模塊化幾乎不可能)
  2. 您需要在C中使用B類才能完成工作W.請在庫D中執行此操作。
  3. 移動你想要的B級「和」從A類從中B級依賴,在C.
0

大多數時候,我必須要解決這樣的問題,我明確地聲明的依賴在POM文件中,然後將EXCLUDES子句添加到有問題的依賴項中。那樣,我確定我得到我想要的版本。其更多的工作,但它可以節省您在WAR文件中擁有12個commons-logging副本。 ;)

1

有幾件事情要做。

首先從神器C開始,通過使用mvn dependency:analyze來驗證真正正在使用的依賴關係,而不是隻在pom.xml中聲明,這個Maven插件作爲調試依賴關係樹的第一步非常有用。可能是這種情況,有一些依賴關係只是聲明但未使用,和/或已使用但未聲明等。

一旦您驗證了依賴關係樹的實際狀態,那麼您應該開始移動事物,如果你的依賴分析步驟沒有顯示任何可以輕易解決的主要問題。

我不知道你的問題有多深,因爲你還沒有發佈任何配置和或代碼剪斷,但你可以在C的pom.xml類似嘗試:

<dependency> 
     <groupId>org.sample</groupId> 
     <artifactId>module-b</artifactId> 
      <exclusions> 
       <exclusion> 
       <groupId>org.sample</groupId> 
       <artifactId>module-c</artifactId> 
       </exclusion> 
      </exclusions> 
    </dependency> 

要排除C相關性從B's那裏繼承傳遞到A's。

5

這不應該發生。我最常做的是有一個模塊結構是這樣的:

root 
    - api (interfaces, enums and custom exceptions only) 
    - impl (standard implementation of api -> dependency to api) 
    - server (runtime dependency to impl, compile time to api only) 
    - client (dependency to api only) 

比方說,我們有api模塊的接口Person。現在在impl模塊中,您將有一個類JpaPerson,因爲impl使用JPA。但是,這些是客戶端和服務器現在不需要的細節,所以您不應該(並且在我的設計中不能)在clientserver中執行new JpaPerson()。相反,你就會有一個接口(內api也)被稱爲PersonFactory(當你在談論的人聽起來很可怕,也許它命名爲更加人性化),有這樣的方法:

public interface PersonFactory{ 

    Person findPersonBySsn(String socialSecurityNumber); 
    List<Person> findPersonsByName(String firstName, String lastName); 
    List<Person> findPersonByBirthDate(Date birthDate); 
    Person createPerson(
     String firstName, String lastName, 
     Date birthDate, String socialSecurityNumber 
    ); 

} 

再次,實施此接口位於impl模塊中,但只能在其他模塊中將其作爲接口引用。然後使用dependency injection將東西連接在一起(Spring,SEAM,EJB3等等)。

您提到的情況是代碼處理超出它的責任的結果(請參閱separation of concerns)。

這個設計的一大優點是,您可以單獨重構所有模塊(除api外),而無需更改其他模塊中的代碼。所以如果你想從jpa切換到經典的休眠,你只需要編輯impl。如果要將服務器從軸切換到cxf,只需更改server。這使事情變得更容易。當然,你不會得到循環依賴。


編輯:

一個簡單的(簡單的)解決方案爲你會以引入被包括作爲在,b和c的依賴關係的模塊d。將所有常用代碼移至d。 (實際上將這個d重命名爲a和a,b,c到b,c,d)。

+0

謝謝...非常有用的解釋... – 2010-07-29 08:46:42