有没有办法知道Java程序是从命令行还是从jar文件启动的?

时间:2010-05-20 00:13:22

标签: java validation command-line double-click

我想在控制台中显示一条消息或者弹出一个消息,所以如果没有指定参数,我想知道应该显示哪个

类似的东西:

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

7 个答案:

答案 0 :(得分:18)

直截了当的答案是你无法分辨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()小费。

答案 1 :(得分:4)

我不清楚这个问题,但我会解释它,因为你想要区分以下2

java -jar 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 :(得分:3)

System.console()技巧似乎可以完成这项工作。

以下是另一种选择:类Class getProtectionDomain()中有一种方法,可用于了解该位置的代码来源。

有趣的是,此方法自1.2以来可用。

我知道我以前用过这个,这是original answer erickson

cat

以下是概念证明:

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)视频,可以看到此代码正在运行(并使用Youtube video http://img237.imageshack.us/img237/4301/capturadepantalla201005j.png编写:-o)

{{3}}

答案 3 :(得分:1)

您可以尝试:

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

答案 4 :(得分:0)

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

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

答案 5 :(得分:0)

确实无法判断JVM是如何被调用的。 但是......有一种方法可以支持这一步。 你假设当用户双击JAR时,那么GUI正在运行...... 好。所以让我们扩展这个假设。 检查...从调用类的位置,目录。 检查那个目录.. 假设它是正常用法,当有* .jar文件时,用户必须从jar启动应用程序。 但有一个缺陷是用户也可以点击主类文件。 哈哈哈哈

答案 6 :(得分:0)

您可以使用RuntimeMBean.getInputArguments()获取所有输入参数,这可以用于检测何时启用调试。

编辑:但是,-jar参数不是其中之一。 :(