Java 当前运行的类或JAR文件的位置
我有一个数据库,它正在执行与远程web服务的一些交互。我已经编写了一个自定义Java类来执行交互 根据用户的设置,可以从三个位置之一执行类方法:Java 当前运行的类或JAR文件的位置,java,jar,lotus-notes,Java,Jar,Lotus Notes,我有一个数据库,它正在执行与远程web服务的一些交互。我已经编写了一个自定义Java类来执行交互 根据用户的设置,可以从三个位置之一执行类方法: 在通过LotusNotesJava代理调用的Java脚本库中 在位于用户“jvm/lib/ext”目录中的JAR文件中 在位于用户“jvm/lib”目录(例如,“jvm/lib/custom_dir”)的自定义目录中的JAR文件中。LotusNotesJVM通过使用“JavaUserClassesExt”本地Notes.ini变量了解自定义目录 在我的
//Normally you don't ever want to do this......
Class clazz = ClassLoader.class;
Field field = clazz.getDeclaredField("sys_paths");
field.setAccessible(true);
field.setClass(clazz, null);
try {
//Basically we read in the path and then loop through and remove our current
//directory which is where we tend to "kick off from" rather than where we want
//to run from.
String minusCurrentDir = removeCurrentDirectoryFromPath(System.getProperty("java.library.path");
System.setProperty("java.library.path", minusCurrentDir);
}
finally {
field.setAccessible(true);
}
getProtectionDomain()方法
其结果是:
java.security.AccessControlException: Access denied (java.lang.RuntimePermission getProtectionDomain)
没有任何选项可以更改运行此操作的任何客户端上的任何安全设置
Class.getResource方法
结果:myResourceURL始终为空
ClassLoader.getResource方法
结果:myResourceURL2始终为空
a) 我在上面哪里出错了
及
b) 如何使用其他方法获取当前正在执行的类的位置?您的最后一行代码是
myCL.getresource(myName)
,应该使用myName2
。这可能会引起问题。如果它使用的名称版本带有前导“/”,那么您将无法从ClassLoader.getResource()调用中获得任何信息。它必须没有前导斜杠。如果没有帮助,您也可以尝试:
ClassLoader.getSystemResource(myName2); // name without leading slash
如果这仍然不起作用,那可能是一个安全问题。根据,如果“调用者没有足够的权限获取资源”,它可以返回null。我只知道Java,不知道Lotus,所以我不知道它在什么样的安全环境中运行代码。我通过将代码包装在“AccessController.doPrivileged”块中,成功地克服了这一问题,即:
final String[] myLocationViaProtectionDomain = {null};
AccessController.doPrivileged(new PrivilegedAction(){
public Object run(){
myLocationViaProtectionDomain[0] = getClass().getProtectionDomain().getCodeSource().getLocation().toString();
debug("myLocationViaProtectionDomain: " + myLocationViaProtectionDomain[0]);
return null;
}
});
有趣的是,当JAR文件位于客户机的JVM目录中时,即我最初文章中的第2点和第3点时,这种方法正是我想要的。但是,当从Java脚本库中执行代码时运行相同的代码时,会引发以下异常:
java.security.AccessControlException: Access denied (java.lang.RuntimePermission getProtectionDomain)
这很好,因为至少在1和(2&3)之间有一个区别,我可以正确处理
lekkimworld.com(Twitter:@lekkim)优秀的Mikkel向我指出了这个解决方案,非常感谢他。我不确定这是否有帮助,但我们“切换”了
user.dir(系统属性),以确保应用程序的某个目录“用完”。在我们的例子中,我们有一个通过LotusNotes启动的web start应用程序(它调用一个BAT文件,调用(JAWS)…)
但无论如何,我们要做的是以下几点
//Normally you don't ever want to do this......
Class clazz = ClassLoader.class;
Field field = clazz.getDeclaredField("sys_paths");
field.setAccessible(true);
field.setClass(clazz, null);
try {
//Basically we read in the path and then loop through and remove our current
//directory which is where we tend to "kick off from" rather than where we want
//to run from.
String minusCurrentDir = removeCurrentDirectoryFromPath(System.getProperty("java.library.path");
System.setProperty("java.library.path", minusCurrentDir);
}
finally {
field.setAccessible(true);
}
现在,您可以访问和修改user.dir
属性,或者询问它在哪里。这可能会让您访问您想要的内容(?),或者至少顶部代码可能会有所帮助。谢谢您的评论,Ryan,很好。myName vs myName2的使用只是我原始描述中的一个输入错误,即使用正确的变量名而不使用前面的斜杠时,我得到了相同的行为。感谢您的回答,Chris,但我通过将代码包装在AccessController.doPrivileged
调用中,成功地获得了所需的内容。详情请参见下面我的答案。您可能应该将其标记为您问题的答案。它帮助别人知道你需要做什么。谢谢你的提醒。对StackOverflow来说还是个新手,所以不知道什么是适当的礼仪。我已经标出了答案,以后会记住的!
java.security.AccessControlException: Access denied (java.lang.RuntimePermission getProtectionDomain)
//Normally you don't ever want to do this......
Class clazz = ClassLoader.class;
Field field = clazz.getDeclaredField("sys_paths");
field.setAccessible(true);
field.setClass(clazz, null);
try {
//Basically we read in the path and then loop through and remove our current
//directory which is where we tend to "kick off from" rather than where we want
//to run from.
String minusCurrentDir = removeCurrentDirectoryFromPath(System.getProperty("java.library.path");
System.setProperty("java.library.path", minusCurrentDir);
}
finally {
field.setAccessible(true);
}