Java 如何从源代码生成API版本?

Java 如何从源代码生成API版本?,java,git,maven,Java,Git,Maven,我正在用Java编写一个API接口,我想添加一个方法,客户端将使用该方法检查服务器使用的版本是否相同 我可以添加一个类似于final String VERSION=“v1.2.3”但我想确保版本始终是最新的 我想避免这个事实,即该文件可能不会更新 我在运行时(甚至在maven中的编译时)搜索类似类hash compute的内容,它可能会生成一个带有hash的资源文件 当我使用git时,也许git可以用它的提交散列更新文件中的一个特殊标记,并且在运行时我为API中涉及的每个源返回一个散列代码 我怎

我正在用Java编写一个API接口,我想添加一个方法,客户端将使用该方法检查服务器使用的版本是否相同

我可以添加一个类似于
final String VERSION=“v1.2.3”但我想确保版本始终是最新的

我想避免这个事实,即该文件可能不会更新

我在运行时(甚至在maven中的编译时)搜索类似类hash compute的内容,它可能会生成一个带有hash的资源文件

当我使用git时,也许git可以用它的提交散列更新文件中的一个特殊标记,并且在运行时我为API中涉及的每个源返回一个散列代码

我怎么能做那样的事

  • 创建类似以下内容的类:
  • package.com公司;
    导入java.io.IOException;
    导入java.util.Properties;
    公共类VersionHelper
    {
    静态属性versionProps=新属性();
    静止的
    {
    尝试
    {
    load(VersionHelper.class.getResourceAsStream(“/version.properties”);
    }
    捕获(IOE异常)
    {
    System.err.println(“Version von”+VersionHelper.class.getName()+“kann nicht ermittelt werden”);
    }
    }
    公共静态字符串getArtifactId()
    {
    返回versionProps.getProperty(“工件”);
    }
    公共静态字符串getVersion()
    {
    返回versionProps.getProperty(“版本”);
    }
    公共静态字符串getBuild()
    {
    返回versionProps.getProperty(“构建”);
    }
    公共静态字符串getBuildTimeStamp()
    {
    返回versionProps.getProperty(“buildTimestamp”);
    }
    }
    
  • ../src/main/resources
    中创建文件
    version.properties
    。这是maven的默认资源目录

    artifact=${project.artifactId}
    version=${project.version}
    buildTimestamp=${build.timestamp}
    build=${buildNumber}
    
  • 将这些属性添加到pom.xml

  • 
    ${maven.build.timestamp}
    年月日HH:MM
    
  • 将此添加到pom.xml中的
    部分:

    
    src/main/resources
    真的
    
  • 然后,您可以在项目中使用
    VersionHelper
    中的get方法


  • 好的,这是我的解决方案,这肯定不是最有效的方法,但它确实起到了作用:

    在我的pom.xml中,我添加了以下内容:

    <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-antrun-plugin</artifactId>
        <version>1.8</version>
        <executions>
            <execution>
                <phase>generate-resources</phase>
                <configuration>
                    <target>
                        <macrodef name="gitlog">
                            <attribute name="lfile" />
                            <sequential>
                                <local name="gitHash"/>
                                <exec executable="git" outputproperty="gitHash">
                                    <arg value="log" />
                                    <arg value="--format=%H" />
                                    <arg value="-n" />
                                    <arg value="1" />
                                    <arg value="--" />
                                    <arg value="@{lfile}" />
                                </exec>
                                <concat append="true" destfile="target/classes/api_hashes.txt">@{lfile}:${gitHash}${line.separator}</concat>
                            </sequential>
                        </macrodef>
    
                        <loadfile property="api.classes" srcFile="api_classes.txt" />
    
                        <delete file="target/classes/api_hashes.txt"/>
                        <ac:for list="${api.classes}" param="classFile" delimiter="|" xmlns:ac="antlib:net.sf.antcontrib">
                            <sequential>
                                <gitlog lfile="@{classFile}" />
                            </sequential>
                        </ac:for>
                    </target>
                </configuration>
                <goals>
                    <goal>run</goal>
                </goals>
            </execution>
        </executions>
        <dependencies>
            <dependency>
                <groupId>ant-contrib</groupId>
                <artifactId>ant-contrib</artifactId>
                <version>1.0b3</version>
                <exclusions>
                    <exclusion>
                        <groupId>ant</groupId>
                        <artifactId>ant</artifactId>
                    </exclusion>
                </exclusions>
            </dependency>
        </dependencies>
    </plugin>
    
    
    org.apache.maven.plugins
    maven antrun插件
    1.8
    产生资源
    @{lfile}:${gitshash}${line.separator}
    跑
    抗辩人
    抗辩人
    1.0b3
    蚂蚁
    蚂蚁
    

    我的api_classes.txt文件在一行中包含一个由字符|分隔的类文件(源)列表(无法使用cariage返回),它生成一个文件,其中包含源列表、字符:和搜索源的最后一个git哈希。

    我可能不完全理解您的问题。也许这有点帮助


    由于评论显示您正在使用Maven,请查看
    buildnumber Maven插件
    。还给出了一些很好的使用示例。我已经能够使用这个没有太多麻烦,它非常适合我的账单。我喜欢更进一步,创建一个页面页脚,在我的web应用程序显示的每个页面上公开构建号,以便在我得到一张带有故障单的完整屏幕截图时准确地知道正在使用哪个版本。

    RC,我已经在使用git maven插件,该插件将git哈希写入资源文件。但我的问题是,api中涉及的类可能不是人工制品中的每个类。我想在编译时创建一个像几个类的哈希一样的东西,或者计算一个运行时给算法一个类的列表。我看,也许(关闭投票缩回)注意,你应该考虑所有的API类作为一个整体和版本,这将平滑客户端服务器版本检查感谢。我已经说过了,但是构建时间戳不能使用,我们可以让多个开发人员在不同的计算机上、不同的时间构建相同的api,并且仍然使用相同的api。人工制品版本可能不会被更新(在快照生命周期内甚至更多)。最后我将使用git commit hash,它可能包含对api不重要的类,但这是最简单的方法。事实上,对api工件的修改可能不会显示api兼容性错误,这取决于修改的内容。如果我使用buildnumber插件使用最后一个git提交哈希,即使是最小的修改也会引发api版本差异。我希望能够指定api需要的类的列表。你是对的。这个想法不适合您,除非您可以从将工件打包到(比如)接口jar和实现jar中获益。然后,您可能会注意到仅在接口jar上的哈希值发生了变化——这可能很有用,而且无论如何可能不是一个坏策略
    <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-antrun-plugin</artifactId>
        <version>1.8</version>
        <executions>
            <execution>
                <phase>generate-resources</phase>
                <configuration>
                    <target>
                        <macrodef name="gitlog">
                            <attribute name="lfile" />
                            <sequential>
                                <local name="gitHash"/>
                                <exec executable="git" outputproperty="gitHash">
                                    <arg value="log" />
                                    <arg value="--format=%H" />
                                    <arg value="-n" />
                                    <arg value="1" />
                                    <arg value="--" />
                                    <arg value="@{lfile}" />
                                </exec>
                                <concat append="true" destfile="target/classes/api_hashes.txt">@{lfile}:${gitHash}${line.separator}</concat>
                            </sequential>
                        </macrodef>
    
                        <loadfile property="api.classes" srcFile="api_classes.txt" />
    
                        <delete file="target/classes/api_hashes.txt"/>
                        <ac:for list="${api.classes}" param="classFile" delimiter="|" xmlns:ac="antlib:net.sf.antcontrib">
                            <sequential>
                                <gitlog lfile="@{classFile}" />
                            </sequential>
                        </ac:for>
                    </target>
                </configuration>
                <goals>
                    <goal>run</goal>
                </goals>
            </execution>
        </executions>
        <dependencies>
            <dependency>
                <groupId>ant-contrib</groupId>
                <artifactId>ant-contrib</artifactId>
                <version>1.0b3</version>
                <exclusions>
                    <exclusion>
                        <groupId>ant</groupId>
                        <artifactId>ant</artifactId>
                    </exclusion>
                </exclusions>
            </dependency>
        </dependencies>
    </plugin>