Is there a way to know if a Java program was start

2020-05-21 08:16发布

I want to either display a message in the console or a pop up, so in case a parameter is not specified, I want to know to which should I display

Something like:

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

7条回答
够拽才男人
2楼-- · 2020-05-21 08:40

I'm not clear on the question but I'm going to interpret it as you want to differentiate between the following 2

java -jar fred.jar

and

java package.Main

Here is an outline line of the program

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

The call MonitoredVmUtil.mainClass(vm, false) will either return 'jar' or the name of your main class eg Main.

You have to use $JAVA_HOME/lib/tools.jar to compile and run.

查看更多
我想做一个坏孩纸
3楼-- · 2020-05-21 08:43

The straight forward answer is that you cannot tell how the JVM was launched.

But for the example use-case in your question, you don't really need to know how the JVM was launched. What you really need to know is whether the user will see a message written to the console. And the way to do that would be something like this:

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
    }
 }

The javadoc for Console, while not water tight, strongly hints that a Console object (if it exists) writes to a console and cannot be redirected.

Thanks @Stephen Denne for the !GraphicsEnvironment.isHeadless() tip.

查看更多
兄弟一词,经得起流年.
4楼-- · 2020-05-21 08:49

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

try {
    GraphicsEnvironment.getLocalGraphicsEnvironment();
} catch(Throwable ex) {
    System.out.println("No graphical environment is available.");
}
查看更多
叛逆
5楼-- · 2020-05-21 08:56

The System.console() trick seems to do the work.

Here's an alternative: there's a method in the class Class getProtectionDomain() which may be used to know the source of the code the the location from there.

The funny is, this method is available since 1.2

I knew I used this before, here's the original answer by erickson

Here's the proof of concept:

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

Here's a short ( 1m aprox ) video to see this code running ( and being written with cat :-o )

Youtube video

查看更多
做个烂人
6楼-- · 2020-05-21 08:56

it's true that it is impossible to tell how the JVM was invoked. but... there's a way to side step this. you assumed that when the user double clicked on a JAR, then there's GUI running... ok. so let's extend this assumption. check.. from where the class was invoked, the directory. check that directory.. assuming it's a normal usage, when there's a *.jar file, then the user must've started the app from a jar.. but one flaw is that the user can also click on the main class file. hahahaha

查看更多
神经病院院长
7楼-- · 2020-05-21 09:00

You can try with:

if (System.console() != null) {
    // Console attached to the JVM: command prompt output
    System.out.println("...");
} else {
    // No console: use Swing
}
查看更多
登录 后发表回答