Java 通过工件版本向后兼容
我正在用三个maven项目开发一个RESTful Web应用程序。这是我的maven设置(从一些细节中删除) 客户端(第二版): com.mycompany.app:app model:2.0中的类FooJava 通过工件版本向后兼容,java,xml,maven,Java,Xml,Maven,我正在用三个maven项目开发一个RESTful Web应用程序。这是我的maven设置(从一些细节中删除) 客户端(第二版): com.mycompany.app:app model:2.0中的类Foo package com.mycompany.app.model.v2; public class Foo { private String name; private int age; } 在第一个版本中,一切正常,因为webapp只依赖com.mycompany.app:
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同时依赖这两种方法,但是如何做到呢?
通常当我在这种情况下结束时,我的大脑会发出警报,我解决问题的方式通常会有问题。
但我似乎找不到另一种方法,它不包括其他“更大”的缺点:(
Idees any?问题比Maven更严重。默认情况下,JVM只会加载一个类的一个版本。如果有两个版本的
com.mycompany.app.model.ModelObject
(例如)在程序的类路径上,当一个类请求ModelObject
时,类加载器将输出并加载它找到的第一个类
我在公共web服务中看到的一种处理方法是根据其版本命名所有类。例如,版本1模型类可以放在包com.mycompany.app.model_1
中,版本2模型类可以放在com.mycompany.app.model_2
中。您(和客户端)不过,在这种情况下,最终可能会编写相当多的额外代码
可能更简单的方法是只为您要支持的模型的每个版本托管一个单独的webapp,webapp路径基于模型版本。因此,在这种情况下,版本1 webapp可能托管在http://app.mycompany.com/webapp_1/...
和版本2位于http://app.mycompany.com/webapp_2/...
。(web服务器为每个webapp使用单独的类加载器,因此webapp_1和webapp_2可以使用同一类的不同版本。)
(如果你喜欢冒险,你也可以尝试在一个webapp中为每个模型版本设置自己的类加载器。不过,我不知道我是否推荐这样做。)问题比Maven更严重。默认情况下,JVM将只加载一个类的一个版本。如果程序的类路径上有两个版本的
com.mycompany.app.model.ModelObject
(例如),当其中一个类请求ModelObject
,则类加载器将退出并加载找到的第一个版本
我在公共web服务中看到的一种处理方法是根据其版本命名所有类。例如,版本1模型类可以放在包com.mycompany.app.model_1
中,版本2模型类可以放在com.mycompany.app.model_2
中。您(和客户端)不过,在这种情况下,最终可能会编写相当多的额外代码
可能更简单的方法是只为您要支持的模型的每个版本托管一个单独的webapp,webapp路径基于模型版本。因此,在这种情况下,版本1 webapp可能托管在http://app.mycompany.com/webapp_1/...
和版本2位于http://app.mycompany.com/webapp_2/...
。(web服务器为每个webapp使用单独的类加载器,因此webapp_1和webapp_2可以使用同一类的不同版本。)
(如果你喜欢冒险,你也可以尝试在一个webapp中为每个模型版本设置自己的类加载器。不过,我不知道我是否推荐这样做。)您可以使用将这些工件复制到项目中的一个目录中。复制同一工件的多个版本应该是可以的。尽管这对根据这些不同版本编译代码没有帮助(您可能需要手动配置其他类路径)
或者只需更改每个版本的工件ID。您可以使用将这些工件复制到项目中的一个目录中。复制同一工件的多个版本应该是可以的。尽管这对针对这些不同版本编译代码没有帮助(您可能需要将附加类路径配置为手写)
或者只需更改每个版本的工件ID。所以,回答我自己的问题,这就是我提出的。我认为这是一个非常简单的问题,没有太多的开箱即用 最初我有3件艺术品:
- com.mycompany.app:app客户端
- com.mycompany.app:应用程序模型
- com.mycompany.app:app webapp
- com.mycompany.app:app依赖于
- 插件:maven依赖插件
<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>
<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>
package com.mycompany.app.model.v1;
public class Foo {
private String name;
}
package com.mycompany.app.model.v2;
public class Foo {
private String name;
private int age;
}
<project>
<groupId>com.mycompany.app</groupId>
<artifactId>app-depend</artifactId>
<version>2.0</version>
<packaging>jar</packaging>
<build>
<resources>
<resource>
<!-- this is where 'unpack' puts the files -->
<directory>${project.build.directory}/dependency</directory>
<filtering>false</filtering>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.5.1</version>
<executions>
<execution>
<id>unpack</id>
<!-- we must do the 'unpack' before the building the jar -->
<phase>generate-sources</phase>
<goals>
<goal>unpack</goal>
</goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId>com.mycompany.app</groupId>
<artifactId>app-model</artifactId>
<version>1.0</version>
<type>jar</type>
<includes>com/mycompany/app/model/v1/**</includes>
</artifactItem>
<artifactItem>
<groupId>com.mycompany.app</groupId>
<artifactId>app-model</artifactId>
<version>2.0</version>
<type>jar</type>
<includes>com/mycompany/app/model/v2/**</includes>
</artifactItem>
<!-- future releases will go here -->
</artifactItems>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>