I can't get my .jar files to run. I have read many similar threads but still can't get it working. I can get it to run from the cmd line if I run "java -jar jar_name.jar" from the folder that contains the file. I ran the Jarfix program that is supposed to fix the file association, but it still does not work. When I export from Eclipse it tells me
JAR export finished with warnings. See details for additional information....Exported with compile warnings: Shutdown/src/Shutdown.java
From what I've read, this is not a real issue, it just means there are warnings in your program. I don't think there's any problem with the code, but it's a small program so I've included it anyways. Any help is appreciated.
import java.io.IOException;
import java.util.Scanner;
public class Shutdown {
public static void main(String[] args) throws IOException
{
String os;
String Win = "Windows";
String choice;
os = System.getProperty("os.name");
if(os.contains(Win))
{
System.out.println("Congratulations, you are running "+ os + ".\nYou now have three options.");
do
{
PrintMenu();
Scanner keyboard = new Scanner(System.in);
choice = keyboard.next();
ReturnMenu(choice);//passes user input as argument to method
}
while(choice !="1" || choice != "2" || choice !="3");
}
else
System.out.println("You Are Using A Non-Windows System. Please upgrade.");
}
public static void shutdown() throws IOException
{
Runtime run = Runtime.getRuntime();
Process proc = run.exec("shutdown -s -t 0");
}
public static void restart() throws IOException
{
Runtime run = Runtime.getRuntime();
Process proc = run.exec("shutdown -r -t 0");
}
public static void logoff() throws IOException
{
Runtime run = Runtime.getRuntime();
Process proc = run.exec("shutdown -l");
}
public static void PrintMenu()
{
System.out.println("Please make a selection:"
+ "\n1 - Shut down\n2 - Restart\n3 - Log Off\n");
}
public static void ReturnMenu(String in) throws IOException, NumberFormatException
{
int x;
try
{
x = Integer.parseInt(in);//cast user input to int to be used in switch statement
}
catch (NumberFormatException e)//catches non-number input that can't be case to int
{
x=4;//caught exception sets x to 4 to cause loop to keep running
}
switch (x)
{
case 1:
shutdown();
break;
case 2:
restart();
break;
case 3:
logoff();
break;
default:
System.out.println("Invalid menu selection. Please try again.");
}
}
}
Select your File/Project -- Export -- Runnable JAR -- Select class with main() in
Launch Configuration -- destination
If you want dependencies for your class in the generated JAR, select
1st option (Extract required libraries into generated JAR)
If you don't need them but just your code, select 3rd option (Copy
required libraries into a sub-folder next to generated JAR)
Hope this helps :)
On Windows, a standard Java installation associates double-clicking of .jar files with the javaw.exe program, not java.exe. The difference is that javaw.exe has no console (command window).
Since you have no console, you have no System.in. I haven't had a chance to try it, but my guess is that attempting to read from System.in will result in immediately reaching the end of the stream, which will cause a Scanner's next* methods to throw a NoSuchElementException.
Im summary, you can't use System.in. If you want to prompt the user for input, use Swing or JavaFX.
Additional note: You must not compare Strings using == or != in Java, as those operators compare object references instead of comparing String values. Use the equals method instead. For instance:
while (!choice.equals("1") && !choice.equals("2") && !choice.equals("3"))
Related
Why does the code break when the default case of the switch function is used.
import java.util.Scanner;
public class Main {
static void checkCommand(String command)
{
switch (command) {
case "add" -> System.out.println("added");
case "access" -> System.out.println("accessed");
case "compare" -> System.out.println("compared");
default -> {
System.out.println("Invalid command, please try again");
enterCommand();
}
}
}
static void enterCommand(){
System.out.print(">>> ");
Scanner usrInput = new Scanner(System.in);
String input = usrInput.nextLine();
while (!input.equals("quit")){
checkCommand(input);
System.out.print(">>> ");
input = usrInput.nextLine();
}
}
public static void main(String[] args) {
enterCommand();
}
}
When I enter in "add", "compare", or "access", and then "quit", the program works as intended, but if I enter in anything that is incorrect where it uses the default case, the program breaks and repeatedly asks for input even if the input is "quit". I have tried a few different things to fix it and nothing has worked. I'm trying to keep the switch statement but if there isn't a way to keep it and have the program run as intended I am open to other options.
Your code works for me. The only problem is that I have to enter quit twice, after entering an invalid command, in order for the program to terminate.
Here is output from a sample run of the exact same code as in your question:
>>> access
accessed
>>> add
added
>>> george
Invalid command, please try again
>>> compare
compared
>>> quit
>>> quit
I am required to enter quit twice because method enterCommand is being called from method checkCommand. You don't need to do this. The while loop, in method enterCommand will ensure that the user is prompted again to enter a command – even after [s]he has entered an invalid command.
Calling enterCommand from checkCommand means that you are essentially calling enterCommand recursively. In the above output, I needed to enter quit twice, since I only entered a single, invalid command. I suggest that you run your code in a debugger to understand why you get this behavior.
As #OldDogProgrammer wrote in his comment to your question, you should create a Scanner object only once rather than each time method enterCommand executes.
As #MadProgrammer wrote in his comment, a do-while loop may be more appropriate than a plain while loop.
Also, quit is not an invalid command so I think that you need to handle that command in method checkCommand and the handling is that you just ignore the command. Since you are using switch expressions, I couldn't find a way to "ignore" a case so in the below code I simply print an empty string. Alternatively, you could print an appropriate message such as Good bye, for example.
import java.util.Scanner;
public class Main {
private static Scanner usrInput;
static void checkCommand(String command) {
switch (command) {
case "add" -> System.out.println("added");
case "access" -> System.out.println("accessed");
case "compare" -> System.out.println("compared");
case "quit" -> System.out.print("");
default -> {
System.out.println("Invalid command, please try again");
}
}
}
static void enterCommand() {
String input;
do {
System.out.print(">>> ");
input = usrInput.nextLine();
checkCommand(input);
} while (!input.equals("quit"));
}
public static void main(String[] args) {
usrInput = new Scanner(System.in);
enterCommand();
}
}
Here is the output when I ran the above code:
>>> access
accessed
>>> add
added
>>> George
Invalid command, please try again
>>> compare
compared
>>> quit
As you can see, I only need to enter quit once.
You need to understand the recursive mechanism.
When the latest recursive has done, it needs to do the remaining tasks from previous recursive. I added comments into your code to explain:
static void checkCommand(String command){
switch (command) {
// ...
default: {
System.out.println("Invalid command, please try again");
enterCommand(); // recursive is calling here.
}
}
}
static void enterCommand(){
System.out.print(">>> ");
Scanner usrInput = new Scanner(System.in);
String input = usrInput.nextLine(); // time 1: input: test | time 2: input: quit -> done recursive 1.
while (!input.equals("quit")){
checkCommand(input); // time 1: go to default and call recursive, go to input time 2
System.out.print(">>> "); // Do the remaining task from time 1. In case you input time 3: "quit". the program will exit.
input = usrInput.nextLine();
}
}
The more recursives are called, the more remain tasks need to do. In your code, to quit the program, you need to type "quit" (n + 1) times if the recursive is called n times
Solutions: To quit immediately after typing "quit" in the first time, just remove the recursive call.
default: {
System.out.println("Invalid command, please try again");
}
Can any body please tell me what code is used for clear screen in Java?
For example, in C++:
system("CLS");
What code is used in Java to clear the screen?
Since there are several answers here showing non-working code for Windows, here is a clarification:
Runtime.getRuntime().exec("cls");
This command does not work, for two reasons:
There is no executable named cls.exe or cls.com in a standard Windows installation that could be invoked via Runtime.exec, as the well-known command cls is builtin to Windows’ command line interpreter.
When launching a new process via Runtime.exec, the standard output gets redirected to a pipe which the initiating Java process can read. But when the output of the cls command gets redirected, it doesn’t clear the console.
To solve this problem, we have to invoke the command line interpreter (cmd) and tell it to execute a command (/c cls) which allows invoking builtin commands. Further we have to directly connect its output channel to the Java process’ output channel, which works starting with Java 7, using inheritIO():
import java.io.IOException;
public class CLS {
public static void main(String... arg) throws IOException, InterruptedException {
new ProcessBuilder("cmd", "/c", "cls").inheritIO().start().waitFor();
}
}
Now when the Java process is connected to a console, i.e. has been started from a command line without output redirection, it will clear the console.
You can use following code to clear command line console:
public static void clearScreen() {
System.out.print("\033[H\033[2J");
System.out.flush();
}
Caveats:
This will work on terminals that support ANSI escape codes
It will not work on Windows' CMD
It will not work in the IDE's terminal
For further reading visit this
This is how I would handle it. This method will work for the Windows OS case and the Linux/Unix OS case (which means it also works for Mac OS X).
public final static void clearConsole()
{
try
{
final String os = System.getProperty("os.name");
if (os.contains("Windows"))
{
Runtime.getRuntime().exec("cls");
}
else
{
Runtime.getRuntime().exec("clear");
}
}
catch (final Exception e)
{
// Handle any exceptions.
}
}
⚠️ Note that this method generally will not clear the console if you are running inside an IDE.
A way to get this can be print multiple end of lines ("\n") and simulate the clear screen. At the end clear, at most in the unix shell, not removes the previous content, only moves it up and if you make scroll down can see the previous content.
Here is a sample code:
for (int i = 0; i < 50; ++i) System.out.println();
Try the following :
System.out.print("\033\143");
This will work fine in Linux environment
Create a method in your class like this: [as #Holger said here.]
public static void clrscr(){
//Clears Screen in java
try {
if (System.getProperty("os.name").contains("Windows"))
new ProcessBuilder("cmd", "/c", "cls").inheritIO().start().waitFor();
else
Runtime.getRuntime().exec("clear");
} catch (IOException | InterruptedException ex) {}
}
This works for windows at least, I have not checked for Linux so far. If anyone checks it for Linux please let me know if it works (or not).
As an alternate method is to write this code in clrscr():
for(int i = 0; i < 80*300; i++) // Default Height of cmd is 300 and Default width is 80
System.out.print("\b"); // Prints a backspace
I will not recommend you to use this method.
If you want a more system independent way of doing this, you can use the JLine library and ConsoleReader.clearScreen(). Prudent checking of whether JLine and ANSI is supported in the current environment is probably worth doing too.
Something like the following code worked for me:
import jline.console.ConsoleReader;
public class JLineTest
{
public static void main(String... args)
throws Exception
{
ConsoleReader r = new ConsoleReader();
while (true)
{
r.println("Good morning");
r.flush();
String input = r.readLine("prompt>");
if ("clear".equals(input))
r.clearScreen();
else if ("exit".equals(input))
return;
else
System.out.println("You typed '" + input + "'.");
}
}
}
When running this, if you type 'clear' at the prompt it will clear the screen. Make sure you run it from a proper terminal/console and not in Eclipse.
Runtime.getRuntime().exec(cls) did NOT work on my XP laptop. This did -
for(int clear = 0; clear < 1000; clear++)
{
System.out.println("\b") ;
}
Hope this is useful
By combining all the given answers, this method should work on all environments:
public static void clearConsole() {
try {
if (System.getProperty("os.name").contains("Windows")) {
new ProcessBuilder("cmd", "/c", "cls").inheritIO().start().waitFor();
}
else {
System.out.print("\033\143");
}
} catch (IOException | InterruptedException ex) {}
}
Try this: only works on console, not in NetBeans integrated console.
public static void cls(){
try {
if (System.getProperty("os.name").contains("Windows"))
new ProcessBuilder("cmd", "/c",
"cls").inheritIO().start().waitFor();
else
Runtime.getRuntime().exec("clear");
} catch (IOException | InterruptedException ex) {}
}
This will work if you are doing this in Bluej or any other similar software.
System.out.print('\u000C');
You can use an emulation of cls with
for (int i = 0; i < 50; ++i) System.out.println();
You need to use control characters as backslash (\b) and carriage return (\r). It come disabled by default, but the Console view can interpret these controls.
Windows>Preferences and Run/Debug > Console and select Interpret ASCII control characteres to enabled it
After these configurations, you can manage your console with control characters like:
\t - tab.
\b - backspace (a step backward in the text or deletion of a single character).
\n - new line.
\r - carriage return. ()
\f - form feed.
More information at: https://www.eclipse.org/eclipse/news/4.14/platform.php
You need to use JNI.
First of all use create a .dll using visual studio, that call system("cls").
After that use JNI to use this DDL.
I found this article that is nice:
http://www.planet-source-code.com/vb/scripts/ShowCode.asp?txtCodeId=5170&lngWId=2
Question:
The commands should be passed in to the program as a file with one instruction per line. The English instructions are in the file commands in english.txt and the Spanish instructions are in the file commands in spanish.txt. You call the program by the passing in the instructions as follows:
java ConsoleRobot < commands_in_english.txt
or
java ConsoleRobot < commands_in_spanish.txt
I don't get what the question is asking? Does it want me to have the commands I enter to go to the english text file or does it want me to have all my commands stored in the english text file?
Here is a link to the full question. I got all of it except the last part. Here is a link to my Java file.
import java.util.Scanner;
public class ConsoleRobot extends SmarterRobot {
public static void main(String [] args) {
World yard = new World();
SmarterRobot ringo = new SmarterRobot();
yard.add(ringo,5,4);
yard.addBeeper(5,9);
yard.addBeeper(4,5);
yard.addBeeper(9,4);
yard.addBeeper(9,5);
Scanner scan = new Scanner(System.in);
System.out.println("Enter a command: | Introduzca un comando:");
String command = scan.nextLine();
command = command.toLowerCase();
while (!command.equals("stop") && !command.equals("detener")) {
if ( command.equals("forward") || command.equals("adelante")) {
System.out.println("How far should the robot move?");
int input = scan.nextInt();
ringo.moveNumOfTimes(input);
} else if ( command.equals("right") || command.equals("derecha"))
ringo.turnRight();
else if ( command.equals("left") || command.equals("izquierda")
ringo.turnLeft();
else if ( command.equals("collect") || command.equals("recoger"))
ringo.pickBeeper();
else if ( command.equals("drop") || command.equals("soltar"))
ringo.putBeeper();
System.out.println("Enter a command: | Introduzca un comando:");
command = scan.nextLine();
}
System.out.println("Finished | Terminado");
}
}
You don't need to do any code to accept the file passed with the < operator. As Majora320 wrote, the < operator renders the file to the standard input. In other wrods, your application will read the commands from the file as if it would have been entered from the keyboard.
The problem is with the scan.nextLine() call. This reads a whole line, and that makes impossible processing commands with parameter, e.g. forward 10 since you read in the whole line, not only the command.
The example below reads first a string (in.next()), and may continue with reading the parameter (in.nextInt()) if a command is expected to have a parameter. But it does not read any parameters for the stop command.
public class Robot {
public static void main(final String[] args) {
final Scanner in = new Scanner(System.in);
while (in.hasNext()) {
final String command=in.next();
if (command.equals("forward")) {
final int distance=in.nextInt();
System.out.println("Forwarding "+distance);
}
if (command.equals("stop")) {
System.out.println("Stopping");
}
}
}
}
The other little problem is that you're keep on reading the input until getting a stop command. This means that command files with no ending stop will not stop your application. It is safer to read until there is something to read, i.e. use while (in.hasNext()) to keep on reading.
Note how indentation and empty lines makes the code more readable, and much easier to follow.
The < operator (At least on the *nix terminal) is for passing the text from a file into the stranded input of a program. For example, grep "hello" < myfile.txt is exactly the same as cat myfile.txt | grep "hello". Basically, < is an abbreviation for running cat file | command. So what java ConsoleRobot < commands_in_english.txt means is pass all the lines in commands_in_english.txt to the stranded input of the ConsoleRobot program. That means you just write the instructions to the file and then run the command.
I've wrote a programme to mask the input that a user types in at the command line.
In detail:
When my programme starts, I run a new thread that prints out an asterisk every millisecond via System.out.print("\010*").
Meanwhile my main method reads in the users input via read.nextLine().
When I run this programme in eclipse, the output is an overflow of asterisks (which is what I would expect).
However, when I run this programme from my terminal, I only see an asterisk appear whenever I type a character.
Why is this? I read some other articles saying how the CPU only allocates 6-10% of memory to the command line, whereas a typical IDE gets more than twice this.
My code is shown below just for reference:
import java.util.Scanner;
public class Main {
public static void main(String [] args){
PasswordMasker passwordMasker = new PasswordMasker();
passwordMasker.start();
Scanner scan = new Scanner(System.in);
String password = scan.nextLine();
passwordMasker.stopMasking();
System.out.println("The password is: " + password);
}
}
public class PasswordMasker extends Thread {
private boolean maskInProgress = true;
public void run(){
mask();
}
private void mask() {
while(maskInProgress){
try {
Thread.sleep(1);
System.out.print("\010*");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("Masking stopped");
}
public void stopMasking(){
this.maskInProgress = false;
}
}
Because the Eclipse console can't display backspace character (\b or \010),
because of bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=76936
The cmd can display it, that is why your program works as expected in cmd.
However the fix will be available in Eclipse 4.5 M4, according to the bug report.
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");
}
}
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.
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.
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 )
You can try with:
if (System.console() != null) {
// Console attached to the JVM: command prompt output
System.out.println("...");
} else {
// No console: use Swing
}
From http://java.itags.org/java-essentials/15972/
try {
GraphicsEnvironment.getLocalGraphicsEnvironment();
} catch(Throwable ex) {
System.out.println("No graphical environment is available.");
}
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
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. :(