Java: получить правильный ресурс - PullRequest
3 голосов
/ 14 января 2011

У меня есть библиотека 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 дважды. Очевидно, я не делаю это правильно. Как получить правильный файл svnversion.properties в корне файла JAR, содержащего данный класс? (предполагая, что это там)


редактировать: я только что попробовал

InputStream is = cl.getResourceAsStream("/svnversion.properties");

и у него та же проблема. Кажется, я могу получить доступ только к основному файлу jar /svnversion.properties, а не к библиотеке /svnversion.properties.

1 Ответ

2 голосов
/ 14 января 2011

Вы, очевидно, не можете использовать этот подход, так как любой файл svnversion.properties всегда будет использоваться загрузчиком классов. Это то же самое поведение, которое вы видели бы для классов: если два пути с одинаковыми именами находятся в пути к классам, то используется то, что находится на первом месте.

(Запутанный) подход - выяснить, к какому банку принадлежит класс, а затем извлечь 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;
    }
}

Именно поэтому, IMHO, вам, вероятно, было бы лучше сохранить номер версии svn в самом классе как конечные статические переменные (и использовать ключевое слово svn $Revision$).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...