我的团队正在与两个团队合作:服务器团队和客户团队。我们服务器团队将为客户团队提供API调用。 API有许多版本,因此我们需要匹配服务器版本和相应的客户端版本 - 例如,如果服务器版本号比其支持版本大得多并且需要更新,则旧客户端将拒绝工作。 p>
由于上述原因,我们需要将服务器的构建版本发送回客户端。目前,我们通过在Config类中添加静态字段来实现此目的。但是我担心每次构建新服务器时都必须手动增加它 - 特别是当我们每天构建时。这个过程非常容易出错并且不太优雅。
在我的搜索中,我看到很多人建议使用maven插件来管理构建版本。虽然我非常感谢自动进程,但它仍然不会让服务器知道内部版本号。服务器应用程序应该能够通过API调用将其构建版本返回给客户端。
我曾想过在某处编写数字版本(远程数据库,服务器上的文件)。 有没有办法让构建过程自动增加构建版本,但是应用程序本身也可以在运行时检索这个号码?
我们正在使用Maven构建并将Jenkin作为集成构建服务器。
答案 0 :(得分:1)
我通常会阅读Maven在JAR中打包的MANIFEST.MF
文件中的版本。
默认情况下,它看起来像这样:
Manifest-Version: 1.0
Built-By: user
Build-Jdk: 1.6.0_35
Created-By: Apache Maven 3.0.4
Archiver-Version: Plexus Archiver
Name: Artifact
Implementation-Build: 1.14-SNAPSHOT
Version: 1.14-SNAPSHOT
从这个文件中我读取了Version元素并使用它来例如显示应用程序的构建版本(以及例如WAR / EAR中所有打包的jar版本)。 像这样的代码应该工作:
public static String getApplicationVersion() {
String version = null;
try {
final List<VersionsUtil.Version> moduleVersions = VersionsUtil.getModuleVersions(Thread.currentThread().getContextClassLoader());
for (VersionsUtil.Version moduleVersion : moduleVersions) {
if (moduleVersion.name.equals("<NAME OF ARTIFACT TO GET>")) {
version = moduleVersion.version;
break;
}
}
} catch (IOException e) {
// We'll return null...
}
return version;
}
public class VersionsUtil {
private static final Logger LOG = LoggerFactory.getLogger(VersionsUtil.class);
/**
* Returns a list of the module versions available for the given class loader.
*
* @param classLoader the class loader to return module versions for
* @return a list of module versions
* @throws IOException in case there's an error reading the manifest
*/
public static List<Version> getModuleVersions(final ClassLoader classLoader) throws IOException {
return processResources(classLoader.getResources("META-INF/MANIFEST.MF"));
}
private static List<Version> processResources(final Enumeration<URL> resources) throws IOException {
final List<Version> moduleVersions = new ArrayList();
while (resources.hasMoreElements()) {
URL resource = resources.nextElement();
Version v = process(resource);
if (v != null) {
moduleVersions.add(v);
}
}
return moduleVersions;
}
private static Version process(final URL resource) {
try {
Properties p = readResource(resource);
return createVersion(p);
} catch (IOException e) {
LOG.warn("Failed to read resource: " + resource, e);
return null;
}
}
private static Version createVersion(final Properties p) {
Object name = p.get("Name");
if (name != null) {
return new Version((String) name, (String) p.get("Version"));
}
return null;
}
private static Properties readResource(final URL resource) throws IOException {
LOG.trace("Reading resource: " + resource);
InputStream is = resource.openStream();
Properties p = new Properties();
p.load(is);
is.close();
return p;
}
public static final class Version {
String name;
String version;
private Version(final String name, final String version) {
this.name = name;
this.version = version;
}
}
}
更新:
如果您想在MANIFEST.MF
中使用Jenkins构建编号,则可以使用以下内容配置POM.XML
:
...
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<version>2.2</version>
<configuration>
<archive>
<manifestSections>
<manifestSection>
<name>${project.name} (${project.artifactId})</name>
<manifestEntries>
<Version>${project.version}${build.number}</Version>
</manifestEntries>
</manifestSection>
</manifestSections>
</archive>
</configuration>
</plugin>
...
<properties>
<build.number />
</properties>
...
如果您对标记WAR / EAR文件感兴趣,则必须相应地添加清单配置。
然后在Jenkins作业配置中,只需将BUILD_NUMBER
参数传递给maven进程,如下所示:-Dbuild.number=$BUILD_NUMBER
。