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 个解决方案
#1
17
The straight forward answer is that you cannot tell how the JVM was launched.
直截了当的答案是,您无法分辨JVM是如何启动的。
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:
但是对于您的问题中的示例用例,您并不需要知道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
}
}
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.
控制台的javadoc虽然不防水,但强烈暗示Console对象(如果存在)写入控制台并且无法重定向。
Thanks @Stephen Denne for the !GraphicsEnvironment.isHeadless()
tip.
感谢@Stephen Denne的!GraphicsEnvironment.isHeadless()提示。
#2
4
I'm not clear on the question but I'm going to interpret it as you want to differentiate between the following 2
我不清楚这个问题,但我会解释它,因为你想要区分以下2
java -jar fred.jar
java -jar fred.jar
and
和
java package.Main
java包。主
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
.
调用MonitoredVmUtil.mainClass(vm,false)将返回'jar'或主类的名称,例如Main。
You have to use $JAVA_HOME/lib/tools.jar
to compile and run.
您必须使用$ JAVA_HOME / lib / tools.jar进行编译和运行。
#3
2
The System.console()
trick seems to do the work.
System.console()技巧似乎可以完成这项工作。
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.
这里有一个替代方法:类getProtectionDomain()中有一个方法,它可以用来从那里知道代码的来源。
The funny is, this method is available since 1.2
有趣的是,这种方法从1.2开始就可用
I knew I used this before, here's the original answer by erickson
我知道我以前用过这个,这是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 )
这是一个短的(1m aprox)视频,看这个代码正在运行(并用cat编写:-o)
Youtube video http://img237.imageshack.us/img237/4301/capturadepantalla201005j.png
Youtube视频http://img237.imageshack.us/img237/4301/capturadepantalla201005j.png
#4
1
You can try with:
您可以尝试:
if (System.console() != null) {
// Console attached to the JVM: command prompt output
System.out.println("...");
} else {
// No console: use Swing
}
#5
0
From http://java.itags.org/java-essentials/15972/
来自http://java.itags.org/java-essentials/15972/
try {
GraphicsEnvironment.getLocalGraphicsEnvironment();
} catch(Throwable ex) {
System.out.println("No graphical environment is available.");
}
#6
0
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
确实无法告诉JVM是如何被调用的。但是......有一种方法可以支持这一步。你假设当用户双击JAR时,那么GUI正在运行......好吧。所以让我们扩展这个假设。检查..从调用类的位置,目录。检查该目录..假设它是正常用法,当有* .jar文件时,那么用户必须从jar启动应用程序..但是一个缺陷是用户也可以单击主类文件。哈哈哈哈
#7
0
You can get all the input arguments with RuntimeMBean.getInputArguments(), this can be used to detect when debugging is enabled.
您可以使用RuntimeMBean.getInputArguments()获取所有输入参数,这可用于检测何时启用调试。
EDIT: However, the -jar argument isn't one of them. :(
编辑:但是,-jar参数不是其中之一。 :(
#1
17
The straight forward answer is that you cannot tell how the JVM was launched.
直截了当的答案是,您无法分辨JVM是如何启动的。
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:
但是对于您的问题中的示例用例,您并不需要知道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
}
}
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.
控制台的javadoc虽然不防水,但强烈暗示Console对象(如果存在)写入控制台并且无法重定向。
Thanks @Stephen Denne for the !GraphicsEnvironment.isHeadless()
tip.
感谢@Stephen Denne的!GraphicsEnvironment.isHeadless()提示。
#2
4
I'm not clear on the question but I'm going to interpret it as you want to differentiate between the following 2
我不清楚这个问题,但我会解释它,因为你想要区分以下2
java -jar fred.jar
java -jar fred.jar
and
和
java package.Main
java包。主
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
.
调用MonitoredVmUtil.mainClass(vm,false)将返回'jar'或主类的名称,例如Main。
You have to use $JAVA_HOME/lib/tools.jar
to compile and run.
您必须使用$ JAVA_HOME / lib / tools.jar进行编译和运行。
#3
2
The System.console()
trick seems to do the work.
System.console()技巧似乎可以完成这项工作。
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.
这里有一个替代方法:类getProtectionDomain()中有一个方法,它可以用来从那里知道代码的来源。
The funny is, this method is available since 1.2
有趣的是,这种方法从1.2开始就可用
I knew I used this before, here's the original answer by erickson
我知道我以前用过这个,这是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 )
这是一个短的(1m aprox)视频,看这个代码正在运行(并用cat编写:-o)
Youtube video http://img237.imageshack.us/img237/4301/capturadepantalla201005j.png
Youtube视频http://img237.imageshack.us/img237/4301/capturadepantalla201005j.png
#4
1
You can try with:
您可以尝试:
if (System.console() != null) {
// Console attached to the JVM: command prompt output
System.out.println("...");
} else {
// No console: use Swing
}
#5
0
From http://java.itags.org/java-essentials/15972/
来自http://java.itags.org/java-essentials/15972/
try {
GraphicsEnvironment.getLocalGraphicsEnvironment();
} catch(Throwable ex) {
System.out.println("No graphical environment is available.");
}
#6
0
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
确实无法告诉JVM是如何被调用的。但是......有一种方法可以支持这一步。你假设当用户双击JAR时,那么GUI正在运行......好吧。所以让我们扩展这个假设。检查..从调用类的位置,目录。检查该目录..假设它是正常用法,当有* .jar文件时,那么用户必须从jar启动应用程序..但是一个缺陷是用户也可以单击主类文件。哈哈哈哈
#7
0
You can get all the input arguments with RuntimeMBean.getInputArguments(), this can be used to detect when debugging is enabled.
您可以使用RuntimeMBean.getInputArguments()获取所有输入参数,这可用于检测何时启用调试。
EDIT: However, the -jar argument isn't one of them. :(
编辑:但是,-jar参数不是其中之一。 :(