这应该很简单但是花了我几个小时。我在这个网站上找到的所有内容都表明我做得对,但文件仍无法找到。
在jar文件中我有两个文件' CDAkeystore.jks'和' CDAtruststore.jks'在顶层。
然而,当我打电话
securityProps.setProperty("javax.net.ssl.keyStore","CDAkeystore.jks");
我得到一个系统找不到文件请求的错误。
调用此方法的类文件位于通常的包安排中的同一个jar中。
jar文件如下:
com ..... (a lot more class files)
org ..... (lots of class files)
META-INF
CDAtruststore.jks
CDAkeystore.jks
这怎么可能很难?!!
----------添加了INFO ------ n
由于使用路径的对象是开源的,我找到了他们用来加载文件的例程。它是:
InputStream keystoreInputStream = preBufferInputStream(new FileInputStream(keyStoreName));
根据FileInputStream(String name)的文档是
通过打开与实际文件的连接来创建FileInputStream,该文件由路径名称' name'在文件系统中。那么这条道路应该如何表达呢?
答案 0 :(得分:2)
使用YourClass.class.getResourceAsStream()
或this.getClass().getResourceAsStream()
。如果您处于多个类加载器环境中,也可以使用类加载器。
答案 1 :(得分:0)
简而言之,答案是你做不到的。至少在这种情况下。我坚持将文件路径传递给我无法控制的库实现。因此,库方法在假设文件在OS的文件系统中以解压缩的形式存在的情况下访问该文件。它是从Property.setProperty(stringKey,stringPath)获取路径 所以我发现的唯一解决方案是丑陋的黑客攻击。我需要在我的jar中获取资源并将其复制到系统上的文件中。然后我将路径传递给上面的setProperty()方法中的该文件。丑陋的黑客实现如下(如果其他人可以提出一个更好的解决方案,我会很高兴)。它确实解决了这个问题。库例程能够找到我新创建的文件。
/* This evil reads a file as a resource inside a jar and dumps the file where ever
* the loader of this jar/application defines as the current directory. This pain is done
* so the SecurityDomian class can load the file; it cannot access the file from
* the jar. This means the 'name' passed in contains the file name inside the jar
* prefixed with "/" so it is not read with an assumed package extension.
*/
private boolean createFileFromResource(String name)
{
// Dont bother if the file already exists
if(new File(name.replace("/", "")).exists())
{
return true;
}
byte[] keystoreFile = new byte[2048];
ByteArrayOutputStream byteArrayOut = new ByteArrayOutputStream(2048);
// Get the resource
InputStream inputStream = this.getClass().getResourceAsStream(name);
try
{
int bytesRead = 0;
while(true)
{
// Read the resource into the buffer keystoreFile in 2048 byte chunks
bytesRead = inputStream.read(keystoreFile);
if(bytesRead < 0)
{
break;
}
// Copy and append the chunks to the ByteArrayOutputStream (this class
// does the auto-extending of the output array as more chunks are
// added so you don't have to do it.
byteArrayOut.write(keystoreFile, 0, bytesRead);
}
inputStream.close();
// Now create a file at the root of where ever the loader happens to think
// the root is. So remove the "/" in front of the file name
FileOutputStream outputStream = new FileOutputStream(name.replace("/", ""));
// Write out the file. Note you will be left with garbage at that location.
byteArrayOut.writeTo(outputStream);
outputStream.flush();
outputStream.close();
}
catch (IOException e)
{
e.printStackTrace();
return false;
}
return true;
}