向后兼容神器版本

时间:2012-09-17 14:14:32

标签: java xml maven

我正在开发一个包含三个maven项目的RESTful webapp。这是我的maven设置(从一些细节条纹)

客户(第二版):

<project>
    <groupId>com.mycompany.app</groupId>
    <artifactId>app-client</artifactId>
    <version>2.0</version>
    ...
    <dependency>
        <groupId>com.mycompany.app</groupId>
        <artifactId>app-model</artifactId>
        <version>2.0</version>
    </dependency>
</project>

模型(第二版):

<project>
    <groupId>com.mycompany.app</groupId>
    <artifactId>app-model</artifactId>
    <version>2.0</version>
</project>
...
<plugin>
    <groupId>org.jvnet.jaxb2.maven2</groupId>
    <artifactId>maven-jaxb2-plugin</artifactId>
    <configuration>
        <generatePackage>com.mycompany.app.model.v2</generatePackage>
    </configuration>
</plugin>

Webapp(第二版):

<project>
    <groupId>com.mycompany.app</groupId>
    <artifactId>app-webapp</artifactId>
    <version>2.0</version>
    ...
    <dependency>
        <groupId>com.mycompany.app</groupId>
        <artifactId>app-model</artifactId>
        <version>1.0</version>
    </dependency>
    <dependency>
        <groupId>com.mycompany.app</groupId>
        <artifactId>app-model</artifactId>
        <version>2.0</version>
    </dependency>
</project>

对于每个版本,我都会更新模型的包名称,以确保唯一的类名。

com.mycompany.app:app-model:1.0中的Class Foo

package com.mycompany.app.model.v1;

public class Foo {
    private String name;
}

com.mycompany.app:app-model:2.0中的Class Foo

package com.mycompany.app.model.v2;

public class Foo {
    private String name;
    private int age;
}

在第一个版本中一切正常,因为webapp仅依赖于com.mycompany.app:app-model:1.0。 在第二个版本中,maven决定只依赖于com.mycompany.app:app-model:2.0。 这是正常行为,我理解为什么在正常情况下这是好事。 然而。我的Backwords compapility代码(在服务器中)希望使用com.mycompany.app:app-model:1.0中的类,因为该版本中发布的客户端使用这些类。 并且新客户端的代码(版本2.0)希望使用com.mycompany.app:app-model:2.0类。

我确信有一种方法可以欺骗maven依赖两者,但是如何? 通常当我在这种情况下结束时,警报就会出现在我脑海中,而且我的解决问题的方式通常有问题。 但我似乎无法在这里找到另一个approch,这不包括其他“更大”的缺点:( 想要谁?

2 个答案:

答案 0 :(得分:1)

问题比Maven更深入。默认情况下,JVM只会加载一个类的版本。如果com.mycompany.app.model.ModelObject的两个版本(例如)在您的程序的类路径中,当您的某个类请求ModelObject时,类加载器将出去并加载它找到的第一个。

我在公共Web服务中看到的一种方法是根据其版本命名所有类。因此,例如,版本1模型类可以放在com.mycompany.app.model_1中的包com.mycompany.app.model_2和版本2模型类中。在这种情况下,您(和客户端)可能最终会编写相当多的额外代码。

可能更简单的方法是为您要支持的每个版本的模型托管一个单独的Web应用程序,并使用基于模型版本的webapp路径。因此,在这种情况下,版本1 webapp可能会在http://app.mycompany.com/webapp_1/...托管,版本2托管在http://app.mycompany.com/webapp_2/...。 (Web服务器为每个webapp使用单独的类加载器,因此webapp_1和webapp_2可以使用同一类的不同版本。)

(如果你喜欢冒险,你也可以尝试在一个webapp中为每个模型版本设置自己独立的类加载器。我不知道我是否会推荐这个。)

答案 1 :(得分:1)

您可以使用Maven Dependency plugin's copy goal将这些工件复制到项目的目录中。复制同一工件的多个版本应该没问题。虽然它对于针对这些不同版本编译代码还没有帮助(您可能需要将其他类路径配置为手写compiler arguments)。

或者只是更改每个版本的工件ID。

相关问题