que - ¿Hay alguna manera de saber si un programa Java se inició desde la línea de comandos o desde un archivo jar?
java jar classpath (7)
Quiero mostrar un mensaje en la consola o en un mensaje emergente, por lo que, en caso de que no se especifique un parámetro, quiero saber a qué debo mostrarlo
Algo como:
if( !file.exists() ) {
if( fromCommandLine()){
System.out.println("File doesn''t exists");
}else if ( fromDoubleClickOnJar() ) {
JOptionPane.showMessage(null, "File doesn''t exists");
}
}
De http://java.itags.org/java-essentials/15972/
try {
GraphicsEnvironment.getLocalGraphicsEnvironment();
} catch(Throwable ex) {
System.out.println("No graphical environment is available.");
}
El truco System.console()
parece hacer el trabajo.
Aquí hay una alternativa: hay un método en la clase Class
getProtectionDomain() que se puede usar para conocer el origen del código y la ubicación desde allí.
Lo gracioso es que este método está disponible desde 1.2
Sabía que había usado esto antes, aquí está la respuesta original de erickson
Aquí está la prueba de concepto:
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 ");
}
}
}
Aquí hay un video corto (1m aprox) para ver este código en ejecución (y estar escrito con un cat : -o)
Video de Youtube http://img237.imageshack.us/img237/4301/capturadepantalla201005j.png
La respuesta directa es que no puede decir cómo se lanzó la JVM.
Pero para el ejemplo de caso de uso en su pregunta, realmente no necesita saber cómo se lanzó la JVM. Lo que realmente necesita saber es si el usuario verá un mensaje escrito en la consola. Y la forma de hacerlo sería algo como esto:
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
}
}
El javadoc for Console , aunque no es hermético, insinúa que un objeto Console (si existe) escribe en una consola y no se puede redireccionar.
Gracias @Stephen Denne por el consejo !GraphicsEnvironment.isHeadless()
.
No tengo clara la pregunta, pero la interpretaré como desea diferenciar entre los siguientes 2
java -jar fred.jar
y
paquete java. Principal
Aquí hay una línea de esquema del programa
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);
}
La llamada MonitoredVmUtil.mainClass(vm, false)
devolverá '' jar
'' o el nombre de su clase principal, por ejemplo Main
.
$JAVA_HOME/lib/tools.jar
usar $JAVA_HOME/lib/tools.jar
para compilar y ejecutar.
Puede obtener todos los argumentos de entrada con RuntimeMBean.getInputArguments (), esto se puede usar para detectar cuándo se habilita la depuración.
EDITAR: Sin embargo, el argumento -jar no es uno de ellos. :(
Puedes probar con:
if (System.console() != null) {
// Console attached to the JVM: command prompt output
System.out.println("...");
} else {
// No console: use Swing
}
es cierto que es imposible decir cómo se invocó la JVM. pero ... hay una manera de evitar esto. supusiste que cuando el usuario hace doble clic en un JAR, entonces hay una GUI ejecutándose ... ok. entonces, extendamos esta suposición. compruebe ... desde donde se invocó la clase, el directorio. verifique ese directorio ... suponiendo que es un uso normal, cuando hay un archivo * .jar, entonces el usuario debe haber iniciado la aplicación desde un contenedor ... pero un error es que el usuario también puede hacer clic en el archivo de la clase principal. jajajaja