我有一个库foo.jar,其中包含一个svnversion.properties文件(看起来像svnversion=12345M或其他内容)以及class SVNVersion中的以下静态方法:

public static SVNVersion fromString(String s) { ... }
public static SVNVersion fromResources(Class<?> cl) {
    ResourceBundle svnversionResource = ResourceBundle.getBundle(
        "svnversion", Locale.getDefault(), cl.getClassLoader());
    if (svnversionResource.containsKey("svnversion"))
    {
        String svnv = svnversionResource.getString("svnversion");
        return fromString(svnv);
    }
    else
    {
        return null;
    }
}

我也有一个bar.jar库,其中也包含一个svnversion.properties文件(假设它包含svnversion=789)。

但是,当我在class SomeClassInBarJar中的bar.jar中运行以下命令时:
SVNVersion vfoo = SVNVersion.fromResources(SVNVersion.class);
SVNVersion vbar = SVNVersion.fromResources(SomeClassInBarJar.class);

然后打印结果,两次看到789。显然,我没有这样做。如何在包含给定类的jar文件的根目录中获取正确的svnversion.properties文件? (假设它在那里)

编辑:我刚刚尝试
InputStream is = cl.getResourceAsStream("/svnversion.properties");

它有同样的问题。我似乎只能访问主jar文件的/svnversion.properties,而不能访问库的/svnversion.properties

最佳答案

您显然不能使用这种方法,因为任何svnversion.properties文件都将始终用于类加载器。这与您在类中看到的行为相同:如果两个相同名称的类都在类路径上,则使用第一个。

(复杂的)方法是找出一个类所属的jar,然后在该jar中检索svnversion.properties:

public static JarFile getJarFile(Class<?> cl) {
    URL classUrl = cl.getResource(cl.getSimpleName() + ".class");
    if (classUrl != null) {
        try {
            URLConnection conn = classUrl.openConnection();
            if (conn instanceof JarURLConnection) {
                JarURLConnection connection = (JarURLConnection) conn;
                return connection.getJarFile();
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
    return null;
}

public static SVNVersion fromResources(Class<?> cl) {
    JarFile jarFile = getJarFile(cl);
    ZipEntry entry = jarFile.getEntry("svnversion.properties");
    Properties props = new Properties();
    try {
        props.load(jarFile.getInputStream(entry));
    } catch (IOException e) {
        throw new RuntimeException(e);
    }

    if (props.containsKey("svnversion")) {
        String svnv = props.getProperty("svnversion");
        return fromString(svnv);
    } else {
        return null;
    }
}

因此,恕我直言,您最好将类中的svn版本号存储为最终的静态变量(并使用svn $Revision$关键字)。

10-08 17:52