2013-02-17 43 views
1

我需要找出Java程序中遠程Java虛擬機上缺省文件編碼的含義。查找遠程jvm的默認文件編碼

是否有執行Charset.defaultCharset()對遠程虛擬機並獲得其值回...不改變在遠程JVM上運行的程序的方法嗎?

更新:

我試圖找出什麼是默認字符集是WebLogic 11g或12C的WebLogic服務器......我沒有啓動,無法重新啓動,我沒有「權利」在其上部署代碼。

我還需要能夠從我寫的Java程序中確定服務器進程的默認字符集。它可以在與服務器相同的機器上執行......或不在。服務器和我的程序將從相同的環境開始,這是非常令人懷疑的。

我寧願依賴於極少數的假設的方法......所以這通常意味着更多的代碼...

我恐怕無法在服務器上執行Charset.defaultCharset()...所以我不應該說'執行Charset.defaultCharset()'。對於那些人很抱歉。我需要做一些提供與從服務器進程內部執行Charset.defaultCharset()一樣正確的答案。

+1

爲什麼你不能修改程序? – 2013-02-17 16:02:19

+0

@ alex-w:我沒有它的來源 – vkraemer 2013-02-17 16:06:37

+0

你試過visualvm嗎? – Jayan 2013-02-17 16:12:22

回答

0

以下是我最後做...(大致)

mbs = conn.getMBeanServerConnection(); 
    ObjectName runtime = new ObjectName(ManagementFactory.RUNTIME_MXBEAN_NAME); 
    TabularDataSupport foo = 
    (TabularDataSupport) mbs.getAttribute(runtime, "SystemProperties"); 
    for (Iterator<Object> it = foo.values().iterator(); 
         it.hasNext() && null == retVal;) { 
    CompositeDataSupport cds = (CompositeDataSupport) it.next(); 
    for (Iterator<?> iter = cds.values().iterator() ; 
        iter.hasNext() && null == retVal ;) { 
     if ("file.encoding".equals(iter.next()) && iter.hasNext()) 
     retVal = iter.next().toString(); 
    } 

我連接到MBeanServer,然後通過SystemProperties合作,以找到在其他過程中的file.encoding連接結束。

3

編輯:寫我的回答後,我發現它是基於一個錯誤的假設,至少部分地,在Charset.defaultCharset()不能保證總是返回相同的價值。下面的一些方法應該仍然有效,只要它們在與目標應用程序相同的主機上嘗試過,但我當然也推薦閱讀this question的前兩個答案以獲取更多背景信息。

特別地,它可能更容易強行覆蓋file.encoding,而不是試圖找出它實際上是什麼。


作爲javadoc of defaultCharset狀態:虛擬機的啓動期間確定

的默認字符集,並且通常取決於底層操作系統的區域設置和字符集。

意思就是說defaultCharset()是隻讀的內部JVM進程,並且將返回所有JVM進程開始在同一臺機器上相同的字符集,除非他們的環境已明確開始處理(之前如:改變包裝/啓動腳本啓動JVM併爲當前進程及其子進程設置不同的語言環境)。如果您確定這兩個進程是以相同的方式啓動的,那麼Charset.defaultCharset()應該返回與您要求的應用程序相同的Charset

懷着這樣的背景下,並在煩惱/努力的爲了增加:

  1. 如果你的主機運行的是Unix/Linux上,嘗試procfs。例如。 /proc/<vmpid>/environ/proc/<vmpid>/cmdline(在Linux上)將是很好的開始,因爲它們向您展示瞭如何在沒有模糊包裝腳本的情況下啓動實際上。該解決方案還可以獲得積分,因爲它不需要您重新啓動/更改應用程序以進行檢查。需要注意的事項:LANGLC_*變量(介紹到locale on Linux)以及影響語言環境的JVM命令行參數。其他操作系統可能也會有某種形式的過程檢查,您可以使用它來顯示此信息。

  2. 下一步:編譯並在特定的主機/ JVM運行此:

    import java.nio.charset.Charset; 
    
    public class DumpCharset { 
        public static void main(String[] args) { 
        System.out.println(Charset.defaultCharset().displayName()); 
        } 
    } 
    

    如前所述,如果進程以同樣的方式開始,Charset.defaultCharset()應返回相同的值(在同一主機上)。爲了得到非常接近的結果,你甚至可以用包含上面代碼的jar臨時替換應用程序的包含main方法的jar(確保類名匹配)。

  3. 如果這不能爲您提供所需信息(它應該),請嘗試啓動進程以使其接受調試器,附加調試器,然後深入到語言環境,和/或執行類似於以上代碼。

  4. 如果仍然不能爲您提供所需的信息,那麼您可以在上課時使用動態字節碼編織。這可以通過基於加載時織入的現有AOP框架(例如,AspectJ)或直接與ASM 4java.lang.instrument API來實現。要意識到做這項工作是有缺陷的,所以很難判斷這是否合理簡單或者不適合你的情況。但是期待它比上述方法做得更多(更多)。

+0

看起來所有這些方法都取決於相同的「if」:「本地」Java程序和「遠程」Java程序以相同的方式啓動。 – vkraemer 2013-02-17 18:25:27

+0

最後兩個沒有,我一直在談論遠程過程,就像'同一個主機'一樣。 – unthought 2013-02-17 18:39:36