2

これは単純なはずですが、私には何時間もかかりました。このサイトで見つけたものはすべて、正しく実行していることを示していますが、ファイルがまだ見つかりません。

jarファイル内には、トップレベルに2つのファイル「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)のドキュメントによると、これは

実際のファイル(ファイルシステム内のパス名'name'で名前が付けられたファイル)への接続を開くことにより、FileInputStreamを作成します。では、このパスはどのように表現する必要がありますか?

4

2 に答える 2

2

YourClass.class.getResourceAsStream()またはを使用しthis.getClass().getResourceAsStream()ます。複数のクラスローダー環境にいる場合は、クラスローダーを使用することもできます。

于 2012-11-27T15:38:26.593 に答える
0

答えは、要するに、あなたができないということです。少なくともこの状況では。ファイルへのパスを、制御できないライブラリ実装に渡すことに固執しています。したがって、libraryメソッドは、ファイルが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;
}
于 2012-11-30T12:58:28.797 に答える