1

私のチームは、サーバー チームとクライアント チームの 2 つのチームで活動しています。私たちサーバー チームは、クライアント チームが呼び出すための API を提供します。API には多くのバージョンがあるため、サーバー ビルドとそれぞれのクライアント ビルドを一致させる必要があります。たとえば、サーバー ビルド番号がサポート バージョンよりもはるかに大きく、更新が必要な場合、古いクライアントは動作を拒否します。

上記の理由により、サーバーのビルド バージョンをクライアントに送り返す必要があります。現在、Config クラスに静的フィールドを追加することでこれを行っています。しかし、新しいサーバーを構築するたびに手動で値を大きくしなければならないという事実が気になります。このプロセスは非常にエラーが発生しやすく、洗練されたものではありません。

私の検索では、ビルド バージョンを管理するために maven プラグインを使用することを提案する多くの人がいます。自動プロセスには非常に感謝していますが、それでもサーバーにビルド番号が通知されません。サーバー アプリケーションは、API 呼び出しを介してクライアントにビルド バージョンを返すことができる必要があります。

バージョン番号をどこかに書き込むことを考えました(リモートデータベース、サーバー上のファイル)。 ビルド プロセスで自動的にビルド バージョンを増やす方法はありますが、アプリケーション自体も実行中にこの番号を取得できますか?

Maven ビルドを使用し、統合ビルド サーバーとして Jenkin を使用しています。

4

1 に答える 1

1

私は通常、MANIFEST.MFMavenによってJARにパッケージ化されているファイルからバージョンを読み取ります。デフォルトでは、次のようになります。

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;
        }

    }
}

更新:Jenkinsビルド番号が必要な場合は、次のようにMANIFEST.MF構成できます。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

于 2012-10-09T06:13:34.193 に答える