I am using JSSE and have the following code:
private static void setupServerKeystore() throws GeneralSecurityException, IOException {
mServerKeyStore = KeyStore.getInstance( "JKS" );
mServerKeyStore.load(new FileInputStream(iComputer.class.getClassLoader().getResource("res/server.public").getPath()),
"pswd".toCharArray());
}
private static void setupClientKeyStore() throws GeneralSecurityException, IOException {
mClientKeyStore = KeyStore.getInstance( "JKS" );
mClientKeyStore.load(new FileInputStream(iComputer.class.getClassLoader().getResource("res/client.private").getPath()),
mPassphrase.toCharArray());
}
Here is my folder structure:
- iComputer
- src
- com
- ...
- res
- server.public
- client.private
Both of the URLs work within Eclipse and the client executes the handshake successfully. However, when I export this as a .jar file, I get a FileNotFoundException:
> java.io.FileNotFoundException:
> file:/Users/Zack/Downloads/iComputer.jar!/res/server.public (No
> such file or directory)
I have been trying to figure this out for hours with no luck. Any help would be much appreciated.
Alright, so here's what I did to fix the issue (thanks to peeskillet for coming up with the solution). I considered the option of using getResourceAsStream().
This worked fine in Eclipse, but the problem was that I was getting an error when exporting and running the jar file, "error error: sun.security.validator.ValidatorException: No trusted certificate found".
It seems as though I was giving it the wrong path.
JSSE's KeyStore.load()
method will accept any type of InputStream as shown in the documentation. It doesn't necessarily have to be a FileInputStream.
So, here is my file structure:
- iComputer
- src
- com
- ...
- res
- server.public
- client.private
Based off of this file structure, the path that works correctly is "res/server.public"
for both Eclipse and the JAR file. So, here are my revisions to the code from my OP:
private static void setupServerKeystore() throws GeneralSecurityException, IOException {
mServerKeyStore = KeyStore.getInstance( "JKS" );
mServerKeyStore.load(iComputer.class.getClassLoader().getResourceAsStream("res/server.public"),
"pswd".toCharArray());
}
private static void setupClientKeyStore() throws GeneralSecurityException, IOException {
mClientKeyStore = KeyStore.getInstance( "JKS" );
mClientKeyStore.load(iComputer.class.getClassLoader().getResourceAsStream("res/client.private"),
mPassphrase.toCharArray());
}
Do yourself a favor, use this as a reference point for where you are putting your key file(s). This will save you countless hours trying to figure out why you are getting a NullPointerException
or FileNotFoundException
.