0

大まかに言えば、Excel スプレッドシートからデータを読み取り、それをハッシュ マップのリストに格納し、ドーム操作を行い、ステータスを取得し、その情報を Excel スプレッドシートに書き戻すプログラムがあります。現時点では、何らかの例外によってプログラムがクラッシュしたり、プログラムが正常に終了したりする場合は、すべて問題ありません。

現在、ユーザーが Ctrl + C を押して実行を終了した場合の処理​​を試みています。これを行う最善の方法は、独自のシャットダウン フックを実装することであると考えました。

private static class TerminationThread extends Thread
{       
    public void run() {
            for(UserCredential user : creds)
        {
            Accel.setRow(user.getMap(), user.getRowIndex());
        }

        try {
            Accel.writeToFile();
        } catch (IOException e)  {
            e.printStackTrace();
        }
    }
}

Main() で、これをシャットダウンフックとして登録します

TerminationThread sH = new TerminationThread();
Runtime.getRuntime().addShutdownHook(sH);

プログラムがシャットダウンフックに入ると、ファイルに書き込む部分に到達するまですべて問題なく、その後一連の例外をスローし始め、最後にスプレッドシートが破損します。

ここに私の書き込みコードがあります:

public void writeToFile() throws IOException
{
    try 
    {
        fileOut = new FileOutputStream(theFile);
        theWorkbook.write(fileOut);
    } 
    catch (IOException e) 
    {
        throw new IOException("Exception in writeToFile(). " + e);
    }
    finally
    {
        try
        {
            fileOut.flush();
            fileOut.close();
        }
        catch(IOException e)
        {
            throw new IOException("Exception closing FileOutputStream. " + e);
        }
    }
}

私が想定しているのは、書き込みが完了する前にExcelスプレッドシートを処理するオブジェクトが消去されているか、書き込み前にデータを保存するハッシュマップのリストが消去されていることです。

私の問題の可能な解決策としてスレッド結合を見てきましたが、それらを見ると、それらが私の問題の解決策であるとは思いません。

だから私の質問は、どうすればこれを私が望むように機能させることができるかということだと思います

乾杯、マイナート

編集:ここに例外があります

Exception in thread "Thread-4" org.apache.xmlbeans.impl.values.XmlValueDisconnectedException
    at org.apache.xmlbeans.impl.values.XmlObjectBase.check_orphaned(XmlObjectBase.java:1213)
    at org.apache.xmlbeans.impl.values.XmlObjectBase.newCursor(XmlObjectBase.java:243)
    at org.apache.xmlbeans.impl.values.XmlComplexContentImpl.arraySetterHelper(XmlComplexContentImpl.java:1073)
    at org.openxmlformats.schemas.spreadsheetml.x2006.main.impl.CTDefinedNamesImpl.setDefinedNameArray(Unknown Source)
    at org.apache.poi.xssf.usermodel.XSSFWorkbook.saveNamedRanges(XSSFWorkbook.java:1270)
    at org.apache.poi.xssf.usermodel.XSSFWorkbook.commit(XSSFWorkbook.java:1291)
    at org.apache.poi.POIXMLDocumentPart.onSave(POIXMLDocumentPart.java:313)
    at org.apache.poi.POIXMLDocument.write(POIXMLDocument.java:173)
    at com.cba.statuschecker.ExcelManager.writeToFile(ExcelManager.java:179)
    at com.cba.statuschecker.Main$TerminationThread.run(Main.java:495)

EDIT 2:まあ、私は自分の問題を理解しました。私はこれに間違った方法でアプローチしていました。私のコードは正しいですが、唯一の問題は、最終ブロックにファイル書き込みもあるということでした。したがって、私のプログラムが中断することなく最後まで実行されると、例外の原因である書き込みが 2 回実行されます。finally ブロックが実行されたかどうか、およびシャットダウン フックでの書き込みがスキップされたかどうかを確認することで、これを修正しました。

ついに:

finally 
{           
    // Print out statuses
    printStatus();

    for(UserCredential user : creds)
    {
        Accel.setRow(user.getMap(), user.getRowIndex());
    }

    try {
        Accel.writeToFile();
    } catch (IOException e)  {
        e.printStackTrace();
    }

    didFinally = true;

    LOGGER.info(Log("Fin."));
    System.exit(0);
}

シャットダウンフック

private static class TerminationThread extends Thread
{           
    public void run() {
        System.out.println("Shutdown Initiated...");
        if(!didFinally){
            for(UserCredential user : creds)
            {
                Accel.setRow(user.getMap(), user.getRowIndex());
            }

            System.out.println("Writing to file...");
            try {
                Accel.writeToFile();
            } catch (IOException e)  {
                e.printStackTrace();
            }
        }

        System.out.println("Terminated!");
    }
}
4

1 に答える 1