簡體   English   中英

如何從私有類加載器中創建 singleton?

[英]How to create a singleton from within a private classloader?

我有一個由第三方應用程序作為擴展實例化的 Java class。 也就是說,根據第 3 方軟件設計,像我們這樣的客戶將我們的 Java class 注冊到他們的應用程序,他們的應用程序將安裝它以在正確的位置和時間執行自定義邏輯。

我們的自定義 Java class 需要編組和解組 XML,為此它使用 ZAB6632Z.D55A4B37438FA2 因此它需要一個 JAXB 上下文。

我在每次調用時都天真地調用了JAXBContext.newInstance(MyClass.class)並且沒那么快發現這是 memory 泄漏的眾所周知的秘訣。 常見的方法是制作一個(或最多只有幾個)JAXB 上下文以在整個應用程序中共享。

很好,除了調用我的 class 的第三方應用程序在該調用專用的新 ClassLoader 實例上進行每次調用。

因此,即使我將JAXBContext放在static字段或static HashMap<>中,它仍然是調用私有的!

問題

如何在從私有 ClassLoader 實例實例化的 class 中創建 singleton 以在 JVM 之間共享?

我正在考慮兩條可能的路線,但我想就如何使它們中的任何一個起作用或任何人擁有的任何完全不同的方法提出建議。

我的三個想法是:

  1. 在 JVM class 中找到可以寫 object 的地方。 例如,如果System.setProperty可以編寫Object的實例而不僅僅是String ,那么我們的想法是創建 JAXB 上下文並將其放入屬性中,因為可以肯定System已經被實例化並且自定義類加載器實例將繼承它。 但是System.setProperty不采用Object值,所以我不知道這樣做的實用方法。

  2. 以某種方式強制 class 加載到我可以通過 JAXB 上下文存儲的父類或根類加載器上。 我不知道該怎么做。

  3. 使用 ThreadLocal 來存儲 JAXBContexts。 我不認為每次調用都是一個全新的線程(它們可能從線程池中重用),所以這可能是限制我的上下文的方法。 但是如何創建 ThreadLocal 變量以便在實例之間共享? 似乎這給我留下了同樣的問題。

聽起來您的代碼在 3rd 方應用程序中被沙盒化了。 因此,使用staticThreadLocal將無濟於事,因為它只會存在於同一個classloader中,並且如果該類classloader被更改......那么上下文就會丟失。

最接近的解決方案是將上下文注入應用程序代碼。 這不是最好的主意,因為它可能會受到外界的影響並產生意想不到的后果。 請注意,這意味着您在classloader中創建的值將保留在應用程序中,因此創建的classloader將永遠不會被垃圾收集。 還有JAXB jar從何而來的問題。 我從您的代碼而不是第 3 方假設。 這樣 jar 每次都在不同的類加載器中加載,因此從那里共享一個 object 可能會出現問題並且需要一些代理。

老實說,可能會有很多意想不到的結果。

最好的辦法是讓第 3 方為您提供一些 API 來啟用它。

在繼續之前,讓我們看看其他選項:

  • 是否有使用JAXB的替代品? 不會出現相同的 memory 泄漏問題的東西。
  • memory泄漏有那么嚴重嗎? 如果在第 3 方應用程序提供 API 之前存在臨時 memory 泄漏怎么辦。

如果您真的想嘗試注入object,我很樂意提供幫助。 但是,根據經驗,這類事情是混亂的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM