Подтвердить что ты не робот

Есть ли способ узнать, была ли запущена программа Java из командной строки или из файла jar?

Я хочу либо отобразить сообщение в консоли, либо всплывающее окно, поэтому, если параметр не указан, я хочу знать, к какому я должен отображать

Что-то вроде:

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

Ответ 1

Прямой ответ заключается в том, что вы не можете сказать, как была запущена 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
    }
 }

javadoc для Console, хотя и не является водонепроницаемым, сильно намекает, что объект консоли (если он существует) записывает на консоль и не может быть перенаправлен.

Спасибо @Stephen Denne за подсказку !GraphicsEnvironment.isHeadless().

Ответ 2

Я не понимаю вопроса, но я буду интерпретировать его так, как вы хотите различать следующие 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 для компиляции и запуска.

Ответ 3

Уловка System.console(), кажется, делает работу.

Вот альтернатива: есть метод в классе Class getProtectionDomain(), который можно использовать для определения источника кода и местоположения оттуда.

Самое смешное, что этот метод доступен с версии 1.2

Я знал, что использовал это раньше, вот оригинальный ответ Эриксоном

Вот подтверждение концепции:

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 ");
       }
    }
}

Вот короткое видео (примерно 1 м), чтобы увидеть, как этот код работает (и записывается с помощью cat: -o)

Youtube video

Ответ 4

Вы можете попробовать:

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

Ответ 6

Это правда, что невозможно определить, как была вызвана JVM. но... есть способ сделать это шаг. вы предположили, что когда пользователь дважды щелкнул по JAR, тогда там работает GUI... ОК. поэтому распространим это предположение. проверьте.. откуда вызывается класс, каталог. проверьте этот каталог.. предполагая, что это нормальное использование, когда есть файл *.jar, тогда пользователь должен запустить приложение из банки. но один из недостатков заключается в том, что пользователь может также щелкнуть файл основного класса. Хахаха

Ответ 7

Вы можете получить все входные аргументы с помощью RuntimeMBean.getInputArguments(), это можно использовать для обнаружения, когда включена отладка.

EDIT: Однако аргумент -jar не является одним из них.: (