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:
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. :(
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.
From http://java.itags.org/java-essentials/15972/
try {
GraphicsEnvironment.getLocalGraphicsEnvironment();
} catch(Throwable ex) {
System.out.println("No graphical environment is available.");
}
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 )
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
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.