如何解决maven循环问题?

时间:2010-07-28 13:46:27

标签: java maven-2 maven

我有这种依赖情况:

  

C( - >)B - > A - > ç

其中B-> C表示模块C在其pom.xml中与B有依赖关系。

嗯...我想在C中使用B中的一个类,所以我必须把C-> B,但是我收到一个循环错误,你可以看到上面...

你看到任何解决方法吗?我不能在C中用B移动那个类,因为它已经使用了A中的一些类,并且会再次循环。

我试图在C中声明一个接口IAlfa并在B(Alfa)中实现它(但是当我想使用它时,我需要实例化如下:

IAlfa alfa = new Alfa() 

所以我再次需要从B中导入Alfa。

您怎么看?

感谢。

4 个答案:

答案 0 :(得分: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)

假设我们在Person模块中有一个接口api。现在在impl模块中,您有一个类JpaPerson,因为impl使用JPA。但是,这些是客户端和服务器现在不需要的详细信息,因此您不应(在我的设计中不能)在new JpaPerson()client中执行server。相反,你有一个名为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即可。这使事情变得容易多了。当然,你没有获得循环依赖。


编辑:

一个简单(简单)的解决方案是引入一个模块d,它包含在a,b和c中作为依赖项。将所有常用代码移至d。 (实际上将此d重命名为a和a,b,c重命名为b,c,d)。

答案 1 :(得分:2)

这种情况似乎是阶级/图书馆组织不良的症状。

你会合理地进入这种情况似乎很奇怪(如果你想讨论那个,你可以更准确地解释你如何组织你的课程)

如果您完全掌控A,B和C的构成,您至少可以做以下事情:

  1. 将A,B和C合并到一个库中并完成它。 (不推荐 - 它几乎不可能实现良好的模块化)
  2. 您需要在C中使用B类才能完成工作W.这样做可以在库D中工作。
  3. 在C中移动你想要的B类,'和'B类所依赖的A中的类。

答案 2 :(得分: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>

从A的传递中继承C的依赖性。

答案 3 :(得分:0)

大多数情况下,当我必须解决这样的问题时,我在POM文件中显式声明了依赖项,然后向相关的依赖项添加了一个EXCLUDES子句。这样我肯定会得到我想要的版本。它的工作量更大,但它可以使您免于在WAR文件中记录12个公共空间副本。 ;)