java:获取正确的资源
我有一个库java:获取正确的资源,java,resources,Java,Resources,我有一个库foo.jar,其中包含一个svversion.properties文件(看起来像svversion=12345M或其他什么),以及类svversion中的以下静态方法: public static SVNVersion fromString(String s) { ... } public static SVNVersion fromResources(Class<?> cl) { ResourceBundle svnversionResource = Resou
foo.jar
,其中包含一个svversion.properties
文件(看起来像svversion=12345M
或其他什么),以及类svversion
中的以下静态方法:
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;
}
}
然后我打印结果,我看到789
两次。显然,我做得不对。如何在包含给定类的jar文件的根目录中获得正确的svversion.properties
文件?(假设它在那里)
编辑:我刚试过
InputStream is = cl.getResourceAsStream("/svnversion.properties");
它也有同样的问题。我似乎只能访问主jar文件的
/svversion.properties
,而不能访问库的/svversion.properties
您显然不能使用这种方法,因为无论svversion.properties
文件出现的是什么,都将始终使用类加载器。这与您在类中看到的行为相同:如果类路径上有两个同名的类,则使用的是最先出现的任何类
一种(复杂的)方法是找出类所属的jar,然后在该jar中检索svversion.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;
}
}
publicstaticjarfile getJarFile(Class cl){
URL classUrl=cl.getResource(cl.getSimpleName()+“.class”);
if(classUrl!=null){
试一试{
URLConnection conn=classUrl.openConnection();
if(JarURLConnection的连接实例){
JarURLConnection连接=(JarURLConnection)conn;
返回连接。getJarFile();
}
}捕获(IOE异常){
抛出新的运行时异常(e);
}
}
返回null;
}
来自资源的公共静态SV转换(类别cl){
JarFile JarFile=getJarFile(cl);
ZipEntry entry=jarFile.getEntry(“svversion.properties”);
Properties props=新属性();
试一试{
load(jarFile.getInputStream(entry));
}捕获(IOE异常){
抛出新的运行时异常(e);
}
if(道具容器(“转换”)){
字符串svnv=props.getProperty(“svnversion”);
从字符串返回(svnv);
}否则{
返回null;
}
}
这就是为什么,IMHO,您最好将svn版本号作为最终静态变量存储在类中(并使用svn
$Revision$
关键字)。给出不同的类名并不一定意味着不同的类加载器。我认为这样做是不可能的this@Teja:我想出来了。:-)我对如何正确操作很感兴趣。您能解释一下如何操作吗?svn关键字替换的可能重复项,例如$Revision$仅适用于单个文件;我想要在整个签出中运行svnversion.exe的结果。无论如何,问题不只是svn版本,而是从库JAR和应用JAR中获取资源。谢谢你的其他建议。我确实明白了,但很明显你误解了类加载的工作方式。除非你在不同的类装入器中装入不同的JAR,否则你永远无法实现你想要的。“但很明显,你误解了类装入的工作方式。”——我一点也没有误解类装入。我所误解的是getResource()和getResourceStream()以及getResourceBundle()与类加载器协同工作的方式。
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;
}
}