views:

292

answers:

7

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");
    }
 }
+6  A: 

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 ( /* we have a GUI Huston */ ) {
        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.

I'll leave it to someone else to fill in a suitable "we have a GUI" predicate ...

EDIT ... and @Stephen Denne provides the answer !GraphicsEnvironment.isHeadless().

Stephen C
+1 for considering the headless scenario, `GraphicsEnvironment.isHeadless()`
Stephen Denne
My deleted answer also boiled down to this, but you're dependent on whether `*.jar` files are by default associated with `java.exe` or `javaw.exe`. I still think that this is the best answer if you can control your own environment, I don't see better ways.
BalusC
@BalusC - *"My deleted answer also boiled down to this"* - ah, but I sed it so much prittier :-).
Stephen C
Yes, you definitely earned my vote for that :)
BalusC
`GraphicsEnvironment.isHeadless()` only checks a property (useful as a kind of "please don't try" setting). You'd also want to catch `HeadlessException` in case the property wasn't set, but there is no display (or keyboard or mouse) available.
Stephen Denne
A: 

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

try {
    GraphicsEnvironment.getLocalGraphicsEnvironment();
} catch(Throwable ex) {
    System.out.println("No graphical environment is available.");
}
Sijin
Nice one, tested it, but this never throws. I think this is more useful to test if there's any graphics device (headless or not).
BalusC
If I open my console an run a java program, the graphics environment will be there still.
OscarRyz
A: 

You can try with:

if (System.console() != null) {
    // Console attached to the JVM: command prompt output
    System.out.println("...");
} else {
    // No console: use Swing
}
schastar
@schastar - this is incorrect. System.console() can return a non-null value, but System.out may still be redirected. (In fact, I can think of two scenarios ...)
Stephen C
A: 

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

p01ntbl4nk
+4  A: 

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.

Chuk Lee
+2  A: 
OscarRyz
What would you want to show for `java -cp fromjar.jar FromJar`
Stephen Denne
Eh, your question was thus: "How to differentiate if the class was launched as Java Application (as standalone class without `-jar` argument) or as JAR file? (with `-jar` argument)" ? Your initial question namely didn't imply that. I understood that it were JAR files in both cases. Else checking would indeed be very easy...
BalusC
@BalusC, yeap, actually what I need is to know if the user doubleclicked on a jar or if it started from the console. I think the `System.console()` answer is the correct.
OscarRyz
A: 

You can get all the input arguments with RuntimeMBean.getInputArguments(), this can be used to detect when debugging is enabled.

EDIT: However, the -jar argument isn't one of them. :(

Peter Lawrey
It displays false in both cases. :( http://pastebin.com/JDGGBbEu
OscarRyz