2010-05-20 42 views
29

我想要麼顯示在控制檯或彈出一個消息,所以如果沒有指定參數,我想知道我應該顯示哪些有沒有辦法知道Java程序是從命令行還是從jar文件啓動?

喜歡的東西:

if(!file.exists()) { 
    if(fromCommandLine()){ 
     System.out.println("File doesn't exists"); 
    }else if (fromDoubleClickOnJar()) { 
     JOptionPane.showMessage(null, "File doesn't exists"); 
    } 
} 
+1

如果從命令行啓動它,應用程序在沒有GUI的情況下運行嗎? – Jon 2010-05-20 00:26:50

+0

有趣的問題(+1),但非常棘手,對於已刪除的答案抱歉,我意識到這是不可靠的。 – BalusC 2010-05-20 00:33:29

+0

@Jon它在兩種情況下都是通過GUI運行的 – OscarRyz 2010-05-20 00:40:01

回答

16

的直截了當的答案是,你不能說出JVM是如何啓動的。

但是對於您的問題中的示例用例,您並不需要知道JVM是如何啓動的。你需要知道的是真的是否會看到一條消息寫入控制檯。而做到這一點的方法是這樣的:

if (!file.exists()) { 
    Console console = System.console(); 
    if (console != null) { 
     console.format("File doesn't exists%n"); 
    } else if (!GraphicsEnvironment.isHeadless()) { 
     JOptionPane.showMessage(null, "File doesn't exists"); 
    } else { 
     // Put it in the log 
    } 
} 

Console的Javadoc,而不是水緊,強烈暗示一個Console對象(如果存在)寫入到控制檯,不能被重定向。

謝謝@Stephen Denne爲!GraphicsEnvironment.isHeadless()提示。

+0

+1用於考慮無頭情況,'GraphicsEnvironment.isHeadless()' – 2010-05-20 01:10:01

+0

我刪除的答案也歸結爲此,但是您依賴於是否存在'* .jar'文件默認與'java.exe'或'javaw.exe'關聯。如果你能控制自己的環境,我仍然認爲這是最好的答案,但我沒有看到更好的方法。 – BalusC 2010-05-20 01:10:42

+0

@BalusC - *「我刪除的答案也歸結爲這個」* - 啊,但我非常確定:-)。 – 2010-05-20 01:13:30

0

http://java.itags.org/java-essentials/15972/

try { 
    GraphicsEnvironment.getLocalGraphicsEnvironment(); 
} catch(Throwable ex) { 
    System.out.println("No graphical environment is available."); 
} 
+1

不錯的,測試它,但這永遠不會拋出。我認爲這對於測試是否有任何圖形設備(無頭或無頭)更有用。 – BalusC 2010-05-20 00:57:58

+3

如果我打開我的控制檯運行一個Java程序,圖形環境將仍然存在。 – OscarRyz 2010-05-20 01:29:53

1

你可以嘗試:

if (System.console() != null) { 
    // Console attached to the JVM: command prompt output 
    System.out.println("..."); 
} else { 
    // No console: use Swing 
} 
+0

這是不正確的。 System.console()可以返回一個非空值,但S​​ystem.out仍可能被重定向。 (實際上,我可以想到兩種情況......) – 2010-05-20 01:08:43

0

這是真的,這是不可能告訴JVM是如何調用。 但是......有一種方法來支持這一點。 你認爲,當用戶雙擊一個JAR,然後有GUI運行... 好的。所以讓我們擴展這個假設。 檢查..從類的調用,目錄。 檢查目錄.. 假設這是一個正常的使用情況,當有一個* .jar文件,那麼用戶必須已經從jar中啓動應用程序..但是一個缺陷是用戶也可以點擊主類文件。 哈哈哈哈

4

我不是對這個問題不清楚,但我要解釋它,只要你想下面的2

Java的罐子fred.jar

區分的java package.Main

這裏是節目的輪廓線

import sun.jvmstat.monitor.*; 
... 
HostIdentifier hostId = new HostIdentifier("localhost"); 
MonitoredHost monitoredHost = MonitoredHost.getMonitoredHost(hostId); 
Set jvms = monitoredHost.activeVms(); 
for (Object i: jvms) { 
    VmIdentifier id = new VmIdentifier("//" + i + "?mode=r"); 
    MonitoredVm vm = monitoredHost.getMonitoredVm(id, 0); 
    System.out.println(i); 
    System.out.println("\t main class: " + MonitoredVmUtil.mainClass(vm, false)); 
    System.out.println("\t main args: " + MonitoredVmUtil.mainArgs(vm)); 
    System.out.println("\t jvmArgs: " + MonitoredVmUtil.jvmArgs(vm)); 
    monitoredHost.detach(vm); 
} 

致電MonitoredVmUtil.mainClass(vm, false)將返回'jar'或您的主類的名稱,例如Main

您必須使用$JAVA_HOME/lib/tools.jar進行編譯和運行。

2

這個System.console()的伎倆似乎是做了這個工作。

下面是一個替代方法:類ClassgetProtectionDomain()中有一種方法,它可以用來從那裏知道代碼的來源。

有趣的是,這種方法是因爲1.2

我知道我使用此之前可用,這裏的original answer通過erickson

這裏的概念證明:

public class FromJar { 
    public static void main(String [] args) { 
     if (FromJar.class 
       .getProtectionDomain() 
       .getCodeSource() 
       .getLocation() 
       .getFile() 
       .endsWith(".jar")) { 

      javax.swing.JOptionPane.showMessageDialog(null, "Launched from Jar"); 

     } else { 
      System.out.println("Launched NOT from Jar :P "); 
     } 
    } 
} 

這裏有一個短(1m aprox)視頻以查看此代碼正在運行(並正在使用cat:-o寫入)

Youtube video http://img237.imageshack.us/img237/4301/capturadepantalla201005j.png

+1

你想爲'java -cp fromjar.jar FromJar'顯示什麼? – 2010-05-20 10:43:41

+0

呃,你的問題是這樣的:「如何區分類是否作爲Java啓動應用程序(作爲不帶'-jar'參數的獨立類)或JAR文件?(帶'-jar'參數)「?你最初的問題並不意味着這一點。我知道這是兩種情況下的JAR文件。否則檢查確實會很容易... – BalusC 2010-05-20 15:11:09

+0

@BalusC,yeap,實際上我需要知道用戶是否在jar上雙擊或者是否從控制檯啓動。我認爲'System.console()'答案是正確的。 – OscarRyz 2010-05-20 17:01:11

0

您可以使用RuntimeMBean.getInputArguments()獲取所有輸入參數,這可以用於檢測何時啓用調試。

編輯:但是,-jar參數不是其中之一。 :(

+0

它在兩種情況下都顯示爲false。 :(http://pastebin.com/JDGGBbEu – OscarRyz 2010-05-20 21:06:18

相關問題