这个问题说明了一切。
我的特殊情况是当前的工作目录不是jar文件的位置,而是c:\Windows\system32
(我的jar文件是由windows使用右键菜单启动的,我想传递一个文件夹的path作为jar的参数。)
现在我想加载名为config.xml
的配置文件,该文件与jar位于同一文件夹中。当然,该文件的目的是为jar提供设置。对我来说,重要的是xml文件是jar文件的外部,以便于编辑。
我很难加载该文件。 Windows执行
行cmd /k java -jar D:\pathToJarfile\unpacker-0.0.1-SNAPSHOT-jar-with-dependencies.jar
使用cmd /k
调用整个事件会使windows命令提示符处于打开状态,以便我可以看到jar的输出。
我无法使用new File(".")
或System.getProperty("user.dir")
作为相对路径,因为这些函数分别返回C:\Windows\system32\.
和C:\Windows\system32
(这是Windows执行AFAIK所有内容的工作文件夹)。
Launcher.class.getResourceAsStream("/../config.xml")
我也没有成功。由于该路径以/
开头,因此搜索从jar的根节点开始。转到../config.xml
完全指向该文件,但调用返回null
。
有人能指出我正确的方向吗?我真的被困在这里了。这个文件加载的东西真的每次都让我烦恼......
我自己的要求:
java -jar
调用(既不是main(String[] args)
的参数,也不是-Dpath=d:\...
来设置系统属性)< / LI>
除了原始问题之外,在使用Class-Path: .
时,我很难将maven2位置MANIFEST.MF
放入jar-with-dependencies
(BalusC发布的解决方案)。
问题是该行出现在常规jar的MANIFEST文件中,但不是jar-with-dependencies.jar的MANIFEST文件(生成了2个jar文件)。
对于任何关心我如何做的人:
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.2-beta-5</version>
<configuration>
<archive>
<manifest>
<mainClass>${mainClass}</mainClass>
<addClasspath>true</addClasspath>
<!--at first, i tried to place the Class-Path entry
right here using <manifestEntries>. see below -->
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
<executions>
<execution>
<goals>
<goal>attached</goal>
</goals>
<phase>package</phase>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<archive>
<manifest>
<mainClass>${mainClass}</mainClass>
</manifest>
<!--this is the correct placement -->
<manifestEntries>
<Class-Path>.</Class-Path>
</manifestEntries>
</archive>
</configuration>
</execution>
</executions>
</plugin>
答案 0 :(得分:12)
以下是使用Class.getProtectionDomain()的一种可能解决方案:
final Class<?> referenceClass = YourMainClass.class;
final URL url =
referenceClass.getProtectionDomain().getCodeSource().getLocation();
try{
final File jarPath = new File(url.toURI()).getParentFile();
System.out.println(jarPath); // this is the path you want
} catch(final URISyntaxException e){
// etc.
}
YourMainClass
可以替换为jar中的任何类。
来自Class.getProtectionDomain()文档:
Returns the ProtectionDomain of this class.
If there is a security manager installed, this method first calls
the security manager's checkPermission method with a
RuntimePermission("getProtectionDomain") permission to ensure it's
ok to get the ProtectionDomain.
Returns:
the ProtectionDomain of this class
Throws:
SecurityException - if a security manager exists and its
checkPermission method doesn't allow getting the ProtectionDomain.
答案 1 :(得分:6)
要使Launcher.class.getResourceAsStream("/../config.xml")
起作用,您需要将其路径添加到JAR的Class-Path
文件的MANIFEST.MF
条目中。这是正常做法。