日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網為廣大站長提供免費收錄網站服務,提交前請做好本站友鏈:【 網站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

本文介紹了Java:刪除JAR后,類仍被加載的處理方法,對大家解決問題具有一定的參考價值,需要的朋友們下面隨著小編來一起學習吧!

問題描述

我試圖重現一個錯誤,其中JAR被更新(通過Linux機器上的rsync),然后拋出NoClassDefFoundError。更新的JAR沒有變化,但我在考慮這樣一個事實,即文件在類加載時正在傳輸…

我現在正在嘗試復制該錯誤。

我的應用程序啟動時只有一個JAR的類路徑(/opt/test/myjar.jar)

其他JAR位于myjar.jar(/opt/test/lib/mylib.jar)相同路徑下的目錄中。

該庫已注冊到myjar.jarMETA-INF/MANIFEST.MF,文本為

Manifest-Version: 1.0
Built-By: FB
Class-Path: lib/mylib.jar

現在我編寫了一些等待幾秒鐘的代碼,然后使用Class.forName("mylib.MyClass")加載一些類。

然后我將設置文件夾,啟動Java運行時,然后刪除lib/mylib.jar文件,并等待Class.forName失敗。

并且代碼運行正常。我期待的是NoClassDefFoundError。然后我重新運行代碼,拋出了一個NoClassDefFoundError

然后我將mylib.jar讀取到lib目錄,重新運行,一切正常。

然后我使用-verbose:class重新運行代碼,刪除lib/mylib.jar,然后出現此日志。

[Loaded mylib.MyClass from file:/opt/test/lib/mylib.jar`]

所以類加載是在JAR刪除之后發生的。我不明白這為什么管用。
并且以前未從lib/mylib.jar加載任何其他類。

使用的JDK為OpenJDK Runtime Environment corretto-8.302.08.1(Build 1.8.0_302-B08)

我不明白JVM如何從我剛剛刪除的文件加載類。我認為JVM可能會在某個地方緩存這些文件(可能是因為它們在MANIFEST.MF中注冊)。

有人知道這種行為嗎?

P。我用真正的JAR和類測試了這個過程。如果沒有人知道原因,我可以構建一個測試項目。

推薦答案

您使用的系統沒有強制文件鎖定。例如,如果您在Windows下嘗試了相同的操作,則無法同時覆蓋或刪除.jar文件。

類路徑上的JAR文件在JVM啟動時打開,并在運行時保持打開狀態。我們可以使用普通文件操作演示該行為:

Path p = Files.createTempFile(Paths.get(System.getProperty("user.home")),"test",".tmp");
try(FileChannel ch = FileChannel.open(p,
                                 StandardOpenOption.READ, StandardOpenOption.WRITE)) {
  System.out.println("opened " + p);
  int rc = new ProcessBuilder("rm", "-v", p.toString()).inheritIO().start().waitFor();
  System.out.println("rm ran with rc " + rc);
  int w = ch.write(StandardCharsets.US_ASCII.encode("test data"));
  System.out.println("wrote " + w + " bytes into " + p);
  ch.position(0);
  ByteBuffer bb = ByteBuffer.allocate(w);
  do ch.read(bb); while(bb.hasRemaining());
  bb.flip();
  System.out.println("read " + bb.remaining() + " bytes, "
                   + StandardCharsets.US_ASCII.decode(bb));
}
System.out.println("closed, reopening");
try(FileChannel ch = FileChannel.open(p,
                                 StandardOpenOption.READ, StandardOpenOption.WRITE)) {
  System.out.println("opened " + p);
}
catch(IOException ex) {
  System.out.println("Reopening " + p + ": " + ex);
}

打印類似

的內容

opened /home/tux/test722563514590118445.tmp
removed '/home/tux/test722563514590118445.tmp'
rm ran with rc 0
wrote 9 bytes into /home/tux/test722563514590118445.tmp
read 9 bytes, test data
closed, reopening
Reopening /home/tux/test722563514590118445.tmp: java.nio.file.NoSuchFileException: /home/tux/test722563514590118445.tmp

演示了在刪除之后,我們仍然可以從已經打開的文件中寫入和讀取數據,因為只有條目已經從目錄中刪除。JVM現在正在操作一個沒有名稱的文件。但是,一旦此文件句柄關閉,再次嘗試打開它將失敗,因為現在它真的不見了。


然而,覆蓋該文件則是另一回事。打開現有文件時,我們訪問相同的文件并使更改可被察覺。

所以

Path p = Files.createTempFile(Paths.get(System.getProperty("user.home")),"test",".tmp");
try(FileChannel ch = FileChannel.open(p,
                                 StandardOpenOption.READ, StandardOpenOption.WRITE)) {
  System.out.println("opened " + p);
  int w = ch.write(StandardCharsets.US_ASCII.encode("test data"));
  System.out.println("wrote " + w + " bytes into " + p);
  int rc = new ProcessBuilder("cp", "/proc/self/cmdline", p.toString())
      .inheritIO().start().waitFor();
  System.out.println("cp ran with rc " + rc);
  ch.position(0);
  ByteBuffer bb = ByteBuffer.allocate(w);
  do ch.read(bb); while(bb.hasRemaining());
  bb.flip();
  System.out.println("read " + bb.remaining() + " bytes, "
                   + StandardCharsets.US_ASCII.decode(bb));
}

產生類似

的結果

opened /home/tux/test7100435925076742504.tmp
wrote 9 bytes into /home/tux/test7100435925076742504.tmp
cp ran with rc 0
read 9 bytes, cp/proc/

顯示了對已經打開的文件的read操作導致了cp寫入的內容,當然,部分原因是緩沖區的大小預先調整到了Java應用程序寫入的內容。這演示了當一些數據已經被讀取并且應用程序嘗試根據它從舊版本中知道的來解釋新數據時,覆蓋打開的文件會如何造成破壞。


這產生了一種解決方案,可以在不使已經運行的JVM崩潰的情況下更新JAR文件。首先刪除舊的JAR文件,這會讓JVM在將新版本復制到相同位置之前,使用已經打開的、現在是私有的舊文件運行。從系統的角度來看,您有兩個不同的文件。當JVM終止時,舊的將不復存在。替換后啟動的JVM將使用新版本。

這篇關于Java:刪除JAR后,類仍被加載的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,

分享到:
標簽:JAR Java 刪除 加載 類仍被
用戶無頭像

網友整理

注冊時間:

網站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網站吧!
最新入駐小程序

數獨大挑戰2018-06-03

數獨一種數學游戲,玩家需要根據9

答題星2018-06-03

您可以通過答題星輕松地創建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學四六

運動步數有氧達人2018-06-03

記錄運動步數,積累氧氣值。還可偷

每日養生app2018-06-03

每日養生,天天健康

體育訓練成績評定2018-06-03

通用課目體育訓練成績評定